├── .gitattributes
├── .github
├── CODEOWNERS
├── labeler.yml
└── workflows
│ ├── housekeeping.yml
│ ├── labeler.yml
│ ├── quality.yml
│ ├── release.yml
│ └── storybook.yml
├── .gitignore
├── .husky
└── pre-commit
├── .lintstagedrc.js
├── .npmrc
├── .prettierignore
├── .prettierrc.js
├── .vscode
├── extensions.json
└── settings.json
├── .yarn
├── plugins
│ └── @yarnpkg
│ │ └── plugin-after-install.cjs
└── releases
│ └── yarn-4.6.0.cjs
├── .yarnrc.yml
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── docs
├── CONVENTIONS.md
├── TOOLING.md
└── TROUBLESHOOTING.md
├── eslint.config.mjs
├── mise.toml
├── multi-release.config.js
├── package.json
├── packages
├── design-tokens
│ ├── .gitignore
│ ├── CHANGELOG.md
│ ├── README.md
│ ├── config.js
│ ├── eslint.config.mjs
│ ├── nodemon.json
│ ├── package.json
│ ├── src
│ │ ├── actions.js
│ │ ├── build.js
│ │ ├── constants.js
│ │ ├── formats.js
│ │ ├── matchers.js
│ │ ├── tailwindcss
│ │ │ ├── tailwind.config.ts
│ │ │ └── tailwind.theme.ts
│ │ └── transforms.js
│ ├── tokens
│ │ ├── border.js
│ │ ├── color
│ │ │ ├── background.js
│ │ │ ├── base.js
│ │ │ ├── border.js
│ │ │ ├── brand.js
│ │ │ ├── decorative.js
│ │ │ ├── feedback.js
│ │ │ ├── icon.js
│ │ │ ├── stroke.js
│ │ │ └── text.js
│ │ ├── shadow.js
│ │ ├── size
│ │ │ ├── border.js
│ │ │ ├── breakpoint.js
│ │ │ ├── radius.js
│ │ │ └── spacing.js
│ │ ├── style-and-decoration.js
│ │ └── typography.js
│ ├── tsconfig.build.json
│ └── tsconfig.json
└── fractal
│ ├── .gitignore
│ ├── .prettierrc.cjs
│ ├── .storybook
│ ├── DocumentationTemplate.mdx
│ ├── main.ts
│ ├── manager-head.html
│ ├── manager.ts
│ ├── preview-head.html
│ ├── preview.tsx
│ └── theme.ts
│ ├── CHANGELOG.md
│ ├── README.md
│ ├── eslint.config.mjs
│ ├── global.d.ts
│ ├── index.ts
│ ├── package.json
│ ├── postcss.config.cjs
│ ├── public
│ ├── android-chrome-192x192.png
│ ├── android-chrome-384x384.png
│ ├── apple-touch-icon-120x120.png
│ ├── apple-touch-icon-152x152.png
│ ├── apple-touch-icon-180x180.png
│ ├── apple-touch-icon-60x60.png
│ ├── apple-touch-icon-76x76.png
│ ├── apple-touch-icon.png
│ ├── favicon-16x16.png
│ ├── favicon-32x32.png
│ ├── favicon.ico
│ ├── images
│ │ ├── cover_fractal.png
│ │ ├── cover_fractal_old.png
│ │ ├── logo_fractal.png
│ │ ├── logo_pink_black.png
│ │ └── logo_pink_white.png
│ ├── safari-pinned-tab.svg
│ └── site.webmanifest
│ ├── scripts
│ ├── build-stats.sh
│ └── transform-icons-imports.js
│ ├── src
│ ├── ThemeProvider.tsx
│ ├── components
│ │ ├── Autocomplete
│ │ │ ├── Autocomplete.constants.ts
│ │ │ ├── Autocomplete.mdx
│ │ │ ├── Autocomplete.stories.tsx
│ │ │ ├── Autocomplete.tsx
│ │ │ ├── Autocomplete.types.ts
│ │ │ ├── AutocompleteEmpty.mdx
│ │ │ ├── AutocompleteEmpty.stories.tsx
│ │ │ ├── AutocompleteEmpty.tsx
│ │ │ ├── AutocompleteItem.mdx
│ │ │ ├── AutocompleteItem.stories.tsx
│ │ │ ├── AutocompleteItemGroup.mdx
│ │ │ ├── AutocompleteItemGroup.stories.tsx
│ │ │ ├── AutocompleteItemSeparator.mdx
│ │ │ ├── AutocompleteItemSeparator.stories.tsx
│ │ │ ├── AutocompleteLoading.mdx
│ │ │ ├── AutocompleteLoading.stories.tsx
│ │ │ ├── AutocompleteLoading.tsx
│ │ │ └── index.ts
│ │ ├── Avatar
│ │ │ ├── Avatar.constants.ts
│ │ │ ├── Avatar.mdx
│ │ │ ├── Avatar.stories.tsx
│ │ │ ├── Avatar.tsx
│ │ │ ├── Avatar.types.ts
│ │ │ └── index.ts
│ │ ├── Badge
│ │ │ ├── Badge.constants.ts
│ │ │ ├── Badge.mdx
│ │ │ ├── Badge.stories.tsx
│ │ │ ├── Badge.tsx
│ │ │ ├── Badge.types.ts
│ │ │ └── index.ts
│ │ ├── Button
│ │ │ ├── Button.constants.ts
│ │ │ ├── Button.mdx
│ │ │ ├── Button.stories.tsx
│ │ │ ├── Button.tsx
│ │ │ ├── Button.types.ts
│ │ │ └── index.ts
│ │ ├── Card
│ │ │ ├── Card.constants.ts
│ │ │ ├── Card.mdx
│ │ │ ├── Card.stories.tsx
│ │ │ ├── Card.tsx
│ │ │ ├── Card.types.ts
│ │ │ └── index.ts
│ │ ├── Confirm
│ │ │ ├── Confirm.constants.ts
│ │ │ ├── Confirm.mdx
│ │ │ ├── Confirm.stories.tsx
│ │ │ ├── Confirm.tsx
│ │ │ ├── Confirm.types.ts
│ │ │ └── index.ts
│ │ ├── CuteIcon
│ │ │ ├── CuteIcon.constants.ts
│ │ │ ├── CuteIcon.mdx
│ │ │ ├── CuteIcon.stories.tsx
│ │ │ ├── CuteIcon.tsx
│ │ │ ├── CuteIcon.types.ts
│ │ │ └── index.ts
│ │ ├── DateTimePicker
│ │ │ ├── DateTimePicker.constants.ts
│ │ │ ├── DateTimePicker.mdx
│ │ │ ├── DateTimePicker.stories.tsx
│ │ │ ├── DateTimePicker.tsx
│ │ │ ├── DateTimePicker.types.ts
│ │ │ └── index.ts
│ │ ├── Dialog
│ │ │ ├── Dialog.constants.ts
│ │ │ ├── Dialog.mdx
│ │ │ ├── Dialog.stories.tsx
│ │ │ ├── Dialog.tsx
│ │ │ ├── Dialog.types.ts
│ │ │ └── index.ts
│ │ ├── Dropdown
│ │ │ ├── Dropdown.constants.ts
│ │ │ ├── Dropdown.mdx
│ │ │ ├── Dropdown.stories.tsx
│ │ │ ├── Dropdown.tsx
│ │ │ ├── Dropdown.types.ts
│ │ │ ├── DropdownContext.ts
│ │ │ ├── DropdownGroupContext.ts
│ │ │ ├── DropdownItem.mdx
│ │ │ ├── DropdownItem.stories.tsx
│ │ │ ├── DropdownItem.tsx
│ │ │ ├── DropdownItemGroup.mdx
│ │ │ ├── DropdownItemGroup.stories.tsx
│ │ │ ├── DropdownItemGroup.tsx
│ │ │ ├── DropdownItemSeparator.mdx
│ │ │ ├── DropdownItemSeparator.stories.tsx
│ │ │ ├── DropdownItemSeparator.tsx
│ │ │ ├── DropdownRadioGroup.mdx
│ │ │ ├── DropdownRadioGroup.stories.tsx
│ │ │ ├── DropdownRadioGroup.tsx
│ │ │ ├── DropdownRadioItem.mdx
│ │ │ ├── DropdownRadioItem.stories.tsx
│ │ │ ├── DropdownRadioItem.tsx
│ │ │ ├── SubDropdown.mdx
│ │ │ ├── SubDropdown.stories.tsx
│ │ │ ├── SubDropdown.tsx
│ │ │ └── index.ts
│ │ ├── EmojiPicker
│ │ │ ├── Emoji.mdx
│ │ │ ├── Emoji.stories.tsx
│ │ │ ├── Emoji.tsx
│ │ │ ├── EmojiPicker.constants.ts
│ │ │ ├── EmojiPicker.mdx
│ │ │ ├── EmojiPicker.stories.tsx
│ │ │ ├── EmojiPicker.tsx
│ │ │ ├── EmojiPicker.types.ts
│ │ │ └── index.ts
│ │ ├── Header
│ │ │ ├── Header.constants.ts
│ │ │ ├── Header.mdx
│ │ │ ├── Header.stories.tsx
│ │ │ ├── Header.tsx
│ │ │ ├── Header.types.ts
│ │ │ └── index.ts
│ │ ├── InputCheckbox
│ │ │ ├── InputCheckbox.constants.ts
│ │ │ ├── InputCheckbox.mdx
│ │ │ ├── InputCheckbox.stories.tsx
│ │ │ ├── InputCheckbox.tsx
│ │ │ ├── InputCheckbox.types.ts
│ │ │ └── index.ts
│ │ ├── InputDate
│ │ │ ├── InputDate.constants.ts
│ │ │ ├── InputDate.mdx
│ │ │ ├── InputDate.stories.tsx
│ │ │ ├── InputDate.tsx
│ │ │ ├── InputDate.types.ts
│ │ │ └── index.ts
│ │ ├── InputFile
│ │ │ ├── InputFile.constants.ts
│ │ │ ├── InputFile.mdx
│ │ │ ├── InputFile.stories.tsx
│ │ │ ├── InputFile.tsx
│ │ │ ├── InputFile.types.ts
│ │ │ └── index.ts
│ │ ├── InputPhone
│ │ │ ├── InputPhone.constants.ts
│ │ │ ├── InputPhone.mdx
│ │ │ ├── InputPhone.stories.tsx
│ │ │ ├── InputPhone.tsx
│ │ │ ├── InputPhone.types.ts
│ │ │ └── index.ts
│ │ ├── InputPinCode
│ │ │ ├── InputPinCode.constants.ts
│ │ │ ├── InputPinCode.mdx
│ │ │ ├── InputPinCode.stories.tsx
│ │ │ ├── InputPinCode.tsx
│ │ │ ├── InputPinCode.types.ts
│ │ │ └── index.ts
│ │ ├── InputRadio
│ │ │ ├── InputRadio.constants.ts
│ │ │ ├── InputRadio.mdx
│ │ │ ├── InputRadio.stories.tsx
│ │ │ ├── InputRadio.tsx
│ │ │ ├── InputRadio.types.ts
│ │ │ ├── InputRadioContext.ts
│ │ │ ├── InputRadioGroup.mdx
│ │ │ ├── InputRadioGroup.stories.tsx
│ │ │ ├── InputRadioGroup.tsx
│ │ │ └── index.ts
│ │ ├── InputText
│ │ │ ├── InputText.constants.ts
│ │ │ ├── InputText.mdx
│ │ │ ├── InputText.stories.tsx
│ │ │ ├── InputText.tsx
│ │ │ ├── InputText.types.ts
│ │ │ └── index.ts
│ │ ├── Loader
│ │ │ ├── Loader.constants.ts
│ │ │ ├── Loader.mdx
│ │ │ ├── Loader.stories.tsx
│ │ │ ├── Loader.tsx
│ │ │ ├── Loader.types.ts
│ │ │ └── index.ts
│ │ ├── Logo
│ │ │ ├── Logo.constants.ts
│ │ │ ├── Logo.mdx
│ │ │ ├── Logo.stories.tsx
│ │ │ ├── Logo.tsx
│ │ │ ├── Logo.types.ts
│ │ │ └── index.ts
│ │ ├── Menu
│ │ │ ├── Menu.constants.ts
│ │ │ ├── Menu.mdx
│ │ │ ├── Menu.stories.tsx
│ │ │ ├── Menu.tsx
│ │ │ ├── Menu.types.ts
│ │ │ ├── MenuContext.ts
│ │ │ ├── MenuGroupContext.ts
│ │ │ ├── MenuItem.mdx
│ │ │ ├── MenuItem.stories.tsx
│ │ │ ├── MenuItem.tsx
│ │ │ ├── MenuItemGroup.mdx
│ │ │ ├── MenuItemGroup.stories.tsx
│ │ │ ├── MenuItemGroup.tsx
│ │ │ ├── MenuItemSeparator.mdx
│ │ │ ├── MenuItemSeparator.stories.tsx
│ │ │ ├── MenuItemSeparator.tsx
│ │ │ ├── SubMenu.mdx
│ │ │ ├── SubMenu.stories.tsx
│ │ │ ├── SubMenu.tsx
│ │ │ └── index.ts
│ │ ├── Paper
│ │ │ ├── Paper.constants.ts
│ │ │ ├── Paper.mdx
│ │ │ ├── Paper.stories.tsx
│ │ │ ├── Paper.tsx
│ │ │ ├── Paper.types.ts
│ │ │ └── index.ts
│ │ ├── Popover
│ │ │ ├── Popover.constants.ts
│ │ │ ├── Popover.mdx
│ │ │ ├── Popover.stories.tsx
│ │ │ ├── Popover.tsx
│ │ │ ├── Popover.types.ts
│ │ │ └── index.ts
│ │ ├── Progress
│ │ │ ├── Progress.constants.ts
│ │ │ ├── Progress.mdx
│ │ │ ├── Progress.stories.tsx
│ │ │ ├── Progress.tsx
│ │ │ ├── Progress.types.ts
│ │ │ └── index.ts
│ │ ├── ScrollArea
│ │ │ ├── ScrollArea.constants.ts
│ │ │ ├── ScrollArea.mdx
│ │ │ ├── ScrollArea.stories.tsx
│ │ │ ├── ScrollArea.tsx
│ │ │ ├── ScrollArea.types.ts
│ │ │ └── index.ts
│ │ ├── Select
│ │ │ ├── Select.constants.ts
│ │ │ ├── Select.mdx
│ │ │ ├── Select.stories.tsx
│ │ │ ├── Select.tsx
│ │ │ ├── Select.types.ts
│ │ │ ├── SelectEmpty.mdx
│ │ │ ├── SelectEmpty.stories.tsx
│ │ │ ├── SelectEmpty.tsx
│ │ │ ├── SelectGroupContext.ts
│ │ │ ├── SelectItem.mdx
│ │ │ ├── SelectItem.stories.tsx
│ │ │ ├── SelectItem.tsx
│ │ │ ├── SelectItemGroup.mdx
│ │ │ ├── SelectItemGroup.stories.tsx
│ │ │ ├── SelectItemGroup.tsx
│ │ │ ├── SelectItemSeparator.mdx
│ │ │ ├── SelectItemSeparator.stories.tsx
│ │ │ └── index.ts
│ │ ├── Skeleton
│ │ │ ├── Skeleton.constants.ts
│ │ │ ├── Skeleton.mdx
│ │ │ ├── Skeleton.stories.tsx
│ │ │ ├── Skeleton.tsx
│ │ │ ├── Skeleton.types.ts
│ │ │ └── index.ts
│ │ ├── Slider
│ │ │ ├── Slider.constants.ts
│ │ │ ├── Slider.mdx
│ │ │ ├── Slider.stories.tsx
│ │ │ ├── Slider.tsx
│ │ │ ├── Slider.types.ts
│ │ │ └── index.ts
│ │ ├── Stepper
│ │ │ ├── Stepper.constants.ts
│ │ │ ├── Stepper.mdx
│ │ │ ├── Stepper.stories.tsx
│ │ │ ├── Stepper.tsx
│ │ │ ├── Stepper.types.ts
│ │ │ └── index.ts
│ │ ├── Switch
│ │ │ ├── Switch.constants.ts
│ │ │ ├── Switch.mdx
│ │ │ ├── Switch.stories.tsx
│ │ │ ├── Switch.tsx
│ │ │ ├── Switch.types.ts
│ │ │ └── index.ts
│ │ ├── Tabs
│ │ │ ├── Tab.mdx
│ │ │ ├── Tab.stories.tsx
│ │ │ ├── Tab.tsx
│ │ │ ├── TabContent.mdx
│ │ │ ├── TabContent.stories.tsx
│ │ │ ├── TabContent.tsx
│ │ │ ├── Tabs.constants.ts
│ │ │ ├── Tabs.mdx
│ │ │ ├── Tabs.stories.tsx
│ │ │ ├── Tabs.tsx
│ │ │ ├── Tabs.types.ts
│ │ │ └── index.ts
│ │ ├── Tag
│ │ │ ├── Tag.constants.ts
│ │ │ ├── Tag.mdx
│ │ │ ├── Tag.stories.tsx
│ │ │ ├── Tag.tsx
│ │ │ ├── Tag.types.ts
│ │ │ └── index.ts
│ │ ├── Textarea
│ │ │ ├── Textarea.constants.ts
│ │ │ ├── Textarea.mdx
│ │ │ ├── Textarea.stories.tsx
│ │ │ ├── Textarea.tsx
│ │ │ ├── Textarea.types.ts
│ │ │ └── index.ts
│ │ ├── Toggle
│ │ │ ├── Toggle.constants.ts
│ │ │ ├── Toggle.mdx
│ │ │ ├── Toggle.stories.tsx
│ │ │ ├── Toggle.tsx
│ │ │ ├── Toggle.types.ts
│ │ │ └── index.ts
│ │ ├── ToggleGroup
│ │ │ ├── ToggleGroup.constants.ts
│ │ │ ├── ToggleGroup.mdx
│ │ │ ├── ToggleGroup.stories.tsx
│ │ │ ├── ToggleGroup.tsx
│ │ │ ├── ToggleGroup.types.ts
│ │ │ ├── ToggleGroupContext.ts
│ │ │ ├── ToggleGroupItem.mdx
│ │ │ ├── ToggleGroupItem.stories.tsx
│ │ │ ├── ToggleGroupItem.tsx
│ │ │ └── index.ts
│ │ ├── Toolbar
│ │ │ ├── Toolbar.constants.ts
│ │ │ ├── Toolbar.mdx
│ │ │ ├── Toolbar.stories.tsx
│ │ │ ├── Toolbar.tsx
│ │ │ ├── Toolbar.types.ts
│ │ │ ├── ToolbarButton.mdx
│ │ │ ├── ToolbarButton.stories.tsx
│ │ │ ├── ToolbarButton.tsx
│ │ │ ├── ToolbarContext.ts
│ │ │ ├── ToolbarDropdown.mdx
│ │ │ ├── ToolbarDropdown.stories.tsx
│ │ │ ├── ToolbarDropdown.tsx
│ │ │ ├── ToolbarDropdownItem.mdx
│ │ │ ├── ToolbarDropdownItem.stories.tsx
│ │ │ ├── ToolbarDropdownItemGroup.mdx
│ │ │ ├── ToolbarDropdownItemGroup.stories.tsx
│ │ │ ├── ToolbarDropdownItemSeparator.mdx
│ │ │ ├── ToolbarDropdownItemSeparator.stories.tsx
│ │ │ ├── ToolbarSeparator.mdx
│ │ │ ├── ToolbarSeparator.stories.tsx
│ │ │ ├── ToolbarSeparator.tsx
│ │ │ └── index.ts
│ │ ├── Tooltip
│ │ │ ├── Tooltip.constants.ts
│ │ │ ├── Tooltip.mdx
│ │ │ ├── Tooltip.stories.tsx
│ │ │ ├── Tooltip.tsx
│ │ │ ├── Tooltip.types.ts
│ │ │ └── index.ts
│ │ ├── Typography
│ │ │ ├── Typography.constants.ts
│ │ │ ├── Typography.mdx
│ │ │ ├── Typography.stories.tsx
│ │ │ ├── Typography.tsx
│ │ │ ├── Typography.types.ts
│ │ │ └── index.ts
│ │ └── index.ts
│ ├── constants.ts
│ ├── hooks
│ │ ├── index.ts
│ │ └── useTheme.ts
│ ├── index.ts
│ ├── mocks.tsx
│ ├── styles
│ │ ├── global.css
│ │ ├── helpers.ts
│ │ ├── polyfills.css
│ │ └── smartphones.css
│ ├── tests_helpers.ts
│ ├── types.ts
│ └── utils.ts
│ ├── stories
│ ├── Breakpoints.mdx
│ ├── Colors.mdx
│ ├── Iconography.mdx
│ ├── Introduction.mdx
│ ├── Shadows.mdx
│ ├── Spacing.mdx
│ ├── Tokens.mdx
│ └── Typography.mdx
│ ├── tailwind.config.ts
│ ├── tsconfig.build.json
│ ├── tsconfig.json
│ ├── tsup.config.ts
│ └── vite.config.ts
├── renovate.json5
├── scripts
├── check-tokens.sh
├── colors.sh
├── copy-storybook.sh
├── filter-vercel-deployments.sh
├── setup-freezer.sh
└── update-fonts.sh
├── tsconfig.eslint.json
├── tsconfig.json
├── yarn.config.cjs
└── yarn.lock
/.gitattributes:
--------------------------------------------------------------------------------
1 | /.yarn/** linguist-vendored
2 | /.yarn/releases/* binary
3 | /.yarn/plugins/**/* binary
4 |
--------------------------------------------------------------------------------
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | # Code owners
2 | # Read more: https://help.github.com/en/articles/about-code-owners
3 |
4 | * @snowball-tech/engineering
5 |
--------------------------------------------------------------------------------
/.github/labeler.yml:
--------------------------------------------------------------------------------
1 | Design Tokens:
2 | - package/design-tokens/**
3 |
4 | Fractal:
5 | - package/fractal/**
6 |
--------------------------------------------------------------------------------
/.github/workflows/housekeeping.yml:
--------------------------------------------------------------------------------
1 | name: Issues & PRs housekeep
2 |
3 | on:
4 | schedule:
5 | - cron: '30 1 * * *'
6 |
7 | jobs:
8 | stale:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - uses: actions/stale@v9
12 | with:
13 | stale-issue-message: |
14 | This issue didn't had any activity in the last 30 days.
15 |
16 | Without any further action or update, it will be closed in 7 days.
17 |
18 | You can remove the "Stale" label or add a comment to keep it open.
19 | close-issue-message: |
20 | This issue was closed because it has been stalled for 7 days.
21 |
22 | If you think this is still relevant, you can reopen it.
23 | stale-pr-message: |
24 | This pull request didn't had any activity in the last 30 days.
25 |
26 | Without any further action or update, it will be closed in 7 days.
27 |
28 | You can remove the "Stale" label or add a comment to keep it open.
29 | close-pr-message: |
30 | This pull request was closed because it has been stalled for 7 days.
31 |
32 | If you think this is still relevant, you can reopen it.
33 | days-before-stale: 30
34 | exempt-all-milestones: true
35 | exempt-pr-labels: Do no stale
36 |
--------------------------------------------------------------------------------
/.github/workflows/labeler.yml:
--------------------------------------------------------------------------------
1 | # Automatically add a label to a pull request based on the modified files
2 |
3 | name: Pull Request Labeler
4 |
5 | on:
6 | - pull_request_target
7 |
8 | jobs:
9 | triage:
10 | permissions:
11 | contents: read
12 | pull-requests: write
13 |
14 | runs-on: ubuntu-latest
15 |
16 | steps:
17 | - uses: actions/labeler@v5
18 | with:
19 | sync-labels: true
20 |
--------------------------------------------------------------------------------
/.github/workflows/quality.yml:
--------------------------------------------------------------------------------
1 | # This is a Github Workflow that runs lint, formatter and unit tests on every
2 | # push and pull request.
3 |
4 | name: Quality
5 |
6 | on:
7 | push:
8 | branches:
9 | - main
10 |
11 | pull_request:
12 | branches:
13 | - main
14 |
15 | concurrency:
16 | group: ${{ github.workflow }}-${{ github.ref }}
17 | cancel-in-progress: true
18 |
19 | env:
20 | FREEZER_TOKEN: ${{ secrets.FREEZER_TOKEN }}
21 |
22 | jobs:
23 | quality:
24 | name: Checking code quality
25 | runs-on: ubuntu-latest
26 | steps:
27 | - uses: actions/checkout@v4
28 |
29 | - uses: actions/setup-node@v4
30 | with:
31 | node-version: 22.x
32 | cache: yarn
33 |
34 | - name: Setting up dependencies & workspaces
35 | run: yarn install --immutable && yarn run -T setup
36 |
37 | - name: Checking linter
38 | run: yarn run -T lint
39 |
40 | - name: Checking format
41 | run: yarn run -T format
42 |
43 | - name: Checking typings
44 | run: yarn run -T types-check
45 |
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | # This is a Github Workflow that waits for quality and security to be executed
2 | # on the `main` branch.
3 |
4 | # If everything pass it also release all package using Semantic Release.
5 |
6 | name: Release
7 |
8 | on:
9 | push:
10 | branches:
11 | - main
12 |
13 | env:
14 | FREEZER_TOKEN: ${{ secrets.FREEZER_TOKEN }}
15 | NODE_ENV: production
16 |
17 | jobs:
18 | release:
19 | name: Releasing updated packages
20 | runs-on: ubuntu-latest
21 | timeout-minutes: 10
22 | steps:
23 | - uses: actions/checkout@v4
24 | with:
25 | token: ${{ secrets.MACHINE_GITHUB_TOKEN }}
26 |
27 | - uses: actions/setup-node@v4
28 | with:
29 | node-version: 22.x
30 | cache: yarn
31 |
32 | - name: Setting up dependencies & workspaces
33 | run: yarn install --immutable && yarn run -T setup
34 |
35 | - name: Setting up Git to access Freezer
36 | run: yarn run setup-freezer
37 |
38 | - name: Building all packages
39 | run: yarn run -T build
40 |
41 | - name: Waiting for quality to pass
42 | uses: lewagon/wait-on-check-action@v1.3.4
43 | with:
44 | ref: ${{ github.ref }}
45 | check-name: Checking code quality
46 | repo-token: ${{ secrets.GITHUB_TOKEN }}
47 | wait-interval: 10
48 |
49 | - name: Publishing updated public packages to NPM, Git & GitHub
50 | env:
51 | GH_TOKEN: ${{ secrets.MACHINE_GITHUB_TOKEN }}
52 | NPM_TOKEN: ${{ secrets.MACHINE_NPM_TOKEN }}
53 | GIT_AUTHOR_NAME: '@snowball-tech-bot'
54 | GIT_AUTHOR_EMAIL: snowball-bot@snowball.xyz
55 | GIT_COMMITTER_NAME: '@snowball-tech-bot'
56 | GIT_COMMITTER_EMAIL: snowball-bot@snowball.xyz
57 | run: yarn run -T publish-all
58 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Misc. MacOS
2 | **/*.DS_Store
3 |
4 | # Logs
5 | **/logs
6 | **/*.log
7 | **/npm-*.log*
8 | **/yarn-*.log*
9 | **/*.tsbuildinfo
10 | **/vite.config.ts.timestamp*
11 |
12 | # Local testing
13 | *.tgz
14 |
15 | # Cache
16 | **/.eslintcache
17 |
18 | # Coverage
19 | **/coverage
20 |
21 | # Dependencies
22 | **/node_modules
23 | .yarn/*
24 | !.yarn/patches
25 | !.yarn/plugins
26 | !.yarn/releases
27 | !.yarn/sdks
28 | !.yarn/versions
29 |
30 | # Next.JS
31 | **/.next
32 | next-env.d.ts
33 |
34 | # Production
35 | **/build
36 | **/out
37 | **/dist
38 |
39 | # Secret files
40 | **/.env*.local
41 | *.pem
42 |
43 | # IDE
44 | **/.idea
45 | **/*.ntvs*
46 | **/*.njsproj
47 | **/*.sln
48 | **/*.sw?
49 | **/.vscode/*
50 | # Let's keep the extensions.json file because it references all the recommended
51 | # extensions for this workspace. That way, newcomers will receive suggestions.
52 | !.vscode/extensions.json
53 | # Also keeps the settings file because it's critical for VSCode to properly work
54 | # in the mono-repository.
55 | !.vscode/settings.json
56 | # Files from the VSCode "SQLTools" extensions.
57 | **/*.session.sql
58 |
59 | # Pythagora project (https://pythagora.ai/).
60 | .pythagora
61 |
62 | # Storybook.
63 | **/storybook-static*
64 |
65 | # Vercel.
66 | **/.vercel
67 |
68 | # Supabase.
69 | **/supabase/.branches
70 | **/supabase/.temp
71 |
72 | # Misc.
73 | *.bak
74 | scripts/tmp
75 | # This file is only used for the Tailwind VSCode extension.
76 | tailwind.config.cjs
77 |
78 | # PandaCSS.
79 | styled-system*
80 |
--------------------------------------------------------------------------------
/.husky/pre-commit:
--------------------------------------------------------------------------------
1 | yarn lint-staged
2 |
--------------------------------------------------------------------------------
/.lintstagedrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | '!*.{js,cjs,mjs,jsx,ts,tsx,json,json5,jsonc,yml,yaml,md,mdx,css,html}': [
3 | 'prettier --ignore-unknown --cache --write',
4 | ],
5 | '*.{js,cjs,mjs,ts,json,json5,jsonc,mdx,yml,yaml,md}': [
6 | 'eslint --cache --fix',
7 | 'prettier --ignore-unknown --cache --write',
8 | ],
9 | '*.{jsx,tsx,css,html}': [
10 | 'eslint --cache --fix',
11 | 'prettier --ignore-unknown --cache --write',
12 | ],
13 | }
14 |
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | workspaces-update = false
2 | registry=https://registry.npmjs.org/
3 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | *.log
2 | .*
3 | !.*.cjs
4 | !.*.js
5 | !.*.json
6 | !.*.json5
7 | !.*.jsx
8 | !.*.md
9 | !.*.mdx
10 | !.*.mjs
11 | !.*.ts
12 | !.*.tsx
13 | !.*.yaml
14 | !.*.yml
15 | !.github
16 | !.storybook
17 | !.vscode
18 | LICENSE
19 |
20 | mise.toml
21 |
22 | .pnp.*
23 | *.lock
24 | *.tsbuildinfo
25 | vite.config.ts.timestamp*
26 |
27 | **/dist
28 | **/out
29 | **/build
30 |
31 | **/coverage
32 |
33 | **/storybook-static
34 | **/styled-system
35 |
--------------------------------------------------------------------------------
/.prettierrc.js:
--------------------------------------------------------------------------------
1 | module.exports = require('@snowball-tech/prettier-config/.prettierrc-tailwind')
2 |
--------------------------------------------------------------------------------
/.yarn/plugins/@yarnpkg/plugin-after-install.cjs:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | //prettier-ignore
3 | module.exports = {
4 | name: "@yarnpkg/plugin-after-install",
5 | factory: function (require) {
6 | "use strict";var plugin=(()=>{var s=Object.defineProperty;var g=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var C=Object.prototype.hasOwnProperty;var r=(t=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(t,{get:(o,e)=>(typeof require<"u"?require:o)[e]}):t)(function(t){if(typeof require<"u")return require.apply(this,arguments);throw new Error('Dynamic require of "'+t+'" is not supported')});var I=(t,o)=>{for(var e in o)s(t,e,{get:o[e],enumerable:!0})},h=(t,o,e,a)=>{if(o&&typeof o=="object"||typeof o=="function")for(let n of x(o))!C.call(t,n)&&n!==e&&s(t,n,{get:()=>o[n],enumerable:!(a=g(o,n))||a.enumerable});return t};var k=t=>h(s({},"__esModule",{value:!0}),t);var P={};I(P,{default:()=>y});var d=r("@yarnpkg/core");var f=r("@yarnpkg/core"),c={afterInstall:{description:"Hook that will always run after install",type:f.SettingsType.STRING,default:""}};var p=r("clipanion"),u=r("@yarnpkg/core");var m=r("@yarnpkg/shell"),l=async(t,o)=>{let e=t.get("afterInstall"),a=!!t.projectCwd?.endsWith(`dlx-${process.pid}`);return e&&!a?(o&&console.log("Running `afterInstall` hook..."),(0,m.execute)(e,[],{cwd:t.projectCwd||void 0})):0};var i=class extends p.Command{async execute(){let o=await u.Configuration.find(this.context.cwd,this.context.plugins);return l(o,!1)}};i.paths=[["after-install"]];var w={configuration:c,commands:[i],hooks:{afterAllInstalled:async(t,o)=>{if(o?.mode===d.InstallMode.UpdateLockfile)return;if(await l(t.configuration,!0))throw new Error("The `afterInstall` hook failed, see output above.")}}},y=w;return k(P);})();
7 | return plugin;
8 | }
9 | };
10 |
--------------------------------------------------------------------------------
/.yarnrc.yml:
--------------------------------------------------------------------------------
1 | compressionLevel: mixed
2 |
3 | enableConstraintsChecks: true
4 |
5 | enableTelemetry: false
6 |
7 | injectEnvironmentFiles:
8 | - .env.yarn?
9 | - .env.local?
10 |
11 | nodeLinker: node-modules
12 |
13 | npmPublishRegistry: 'https://registry.npmjs.org'
14 |
15 | plugins:
16 | - checksum: 0a2a35fbed2f33f0df1ceb1db51bf72554201f994eaecb86cbc62a295c3d05f7cc44fa8be8e64fc5e1c0bee4f529a17a0cc429ea9e3486ad467443291d5a8e3b
17 | path: .yarn/plugins/@yarnpkg/plugin-after-install.cjs
18 | spec: 'https://raw.githubusercontent.com/mhassan1/yarn-plugin-after-install/v0.6.0/bundles/@yarnpkg/plugin-after-install.js'
19 |
20 | yarnPath: .yarn/releases/yarn-4.6.0.cjs
21 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 Snowball
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/docs/TROUBLESHOOTING.md:
--------------------------------------------------------------------------------
1 | # FAQ & Troubleshooting
2 |
--------------------------------------------------------------------------------
/eslint.config.mjs:
--------------------------------------------------------------------------------
1 | import base from '@snowball-tech/eslint-snowball-config/configs/base.js'
2 | import html from '@snowball-tech/eslint-snowball-config/configs/html.js'
3 | import importConfig from '@snowball-tech/eslint-snowball-config/configs/import.js'
4 | import json from '@snowball-tech/eslint-snowball-config/configs/json.js'
5 | import lodash from '@snowball-tech/eslint-snowball-config/configs/lodash.js'
6 | import markdown from '@snowball-tech/eslint-snowball-config/configs/markdown.js'
7 | import perfectionist from '@snowball-tech/eslint-snowball-config/configs/perfectionist.js'
8 | import prettier from '@snowball-tech/eslint-snowball-config/configs/prettier.js'
9 | import react from '@snowball-tech/eslint-snowball-config/configs/react.js'
10 | import secrets from '@snowball-tech/eslint-snowball-config/configs/secrets.js'
11 | import tailwind from '@snowball-tech/eslint-snowball-config/configs/tailwind.js'
12 | import typescript from '@snowball-tech/eslint-snowball-config/configs/typescript.js'
13 | import yml from '@snowball-tech/eslint-snowball-config/configs/yml.js'
14 |
15 | export default [
16 | ...base,
17 | ...html,
18 | ...json,
19 | ...markdown,
20 | ...yml,
21 | ...secrets,
22 | ...importConfig,
23 | ...typescript,
24 | ...react,
25 | ...lodash,
26 | ...perfectionist,
27 | ...tailwind,
28 | ...prettier,
29 |
30 | {
31 | files: ['packages/design-tokens/src/tailwind.config.ts'],
32 |
33 | rules: {
34 | 'import/no-unresolved': 'off',
35 | },
36 | },
37 |
38 | {
39 | files: ['**/*.md/*.{js,ts,tsx}'],
40 |
41 | rules: {
42 | '@typescript-eslint/no-unused-vars': 'off',
43 | },
44 | },
45 |
46 | {
47 | files: ['**/stories/*.mdx'],
48 |
49 | rules: {
50 | 'markdown/heading-increment': 'off',
51 | 'markdown/no-missing-label-refs': 'off',
52 | },
53 | },
54 | ]
55 |
--------------------------------------------------------------------------------
/mise.toml:
--------------------------------------------------------------------------------
1 | [tools]
2 | node = '22'
3 |
--------------------------------------------------------------------------------
/multi-release.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: '@snowball-tech/semantic-release-config/multi-release.config.js',
3 | }
4 |
--------------------------------------------------------------------------------
/packages/design-tokens/.gitignore:
--------------------------------------------------------------------------------
1 | dist
2 |
--------------------------------------------------------------------------------
/packages/design-tokens/eslint.config.mjs:
--------------------------------------------------------------------------------
1 | // eslint-disable-next-line import/no-relative-packages
2 | import defaultConfig from '../../eslint.config.mjs'
3 |
4 | export default [
5 | ...defaultConfig,
6 |
7 | {
8 | files: ['src/tailwind.config.ts'],
9 |
10 | rules: {
11 | 'import/no-unresolved': 'off',
12 | },
13 | },
14 | ]
15 |
--------------------------------------------------------------------------------
/packages/design-tokens/nodemon.json:
--------------------------------------------------------------------------------
1 | {
2 | "watch": ["tokens/", "src/", "assets/", "config.js"],
3 | "ext": "js,json,json5"
4 | }
5 |
--------------------------------------------------------------------------------
/packages/design-tokens/src/actions.js:
--------------------------------------------------------------------------------
1 | const { execSync } = require('node:child_process')
2 | const path = require('node:path')
3 |
4 | const StyleDictionary = require('style-dictionary')
5 |
6 | const noop = require('lodash/fp/noop')
7 |
8 | StyleDictionary.registerAction({
9 | do: () => {
10 | const constantsPath = path.resolve(__dirname, './constants.js')
11 |
12 | const destinationDirectory = 'dist/web/typescript/'
13 | const destinationPath = path.resolve(
14 | __dirname,
15 | `../${destinationDirectory}`,
16 | )
17 |
18 | execSync(
19 | `yarn to-esm ${constantsPath} --output ${destinationPath} --extension .js --minify --no-comments --noHeader`,
20 | )
21 | console.log(`✔︎ ${destinationDirectory}constants.js (ESM)`)
22 | },
23 | name: 'typescript/copy-constants',
24 | undo: noop,
25 | })
26 |
27 | StyleDictionary.registerAction({
28 | do: () => {
29 | const destinationDirectory = 'dist/web/'
30 |
31 | execSync(`yarn run tsc --outDir ${destinationDirectory}`)
32 | console.log(
33 | `✔︎ ${destinationDirectory}tailwindcss/tailwind.config.js (ESM)`,
34 | )
35 | console.log(
36 | `✔︎ ${destinationDirectory}tailwindcss/tailwind.theme.js (ESM)`,
37 | )
38 | },
39 | name: 'tailwindcss/copy-config',
40 | undo: noop,
41 | })
42 |
--------------------------------------------------------------------------------
/packages/design-tokens/src/build.js:
--------------------------------------------------------------------------------
1 | const StyleDictionary = require('style-dictionary')
2 |
3 | require('./actions')
4 | require('./formats')
5 | require('./transforms')
6 |
7 | const config = require('../config')
8 |
9 | const platforms = Object.keys(config.platforms)
10 |
11 | let message = `Building design tokens on ${platforms.length} platform${
12 | platforms.length > 1 ? 's' : ''
13 | }:`
14 | message =
15 | platforms.length > 1
16 | ? `${message} ${platforms.slice(0, -1).join(', ')} and ${platforms.at(-1)}`
17 | : `${message} ${platforms[0]}`
18 | console.info(`${message}...`)
19 |
20 | const sdInstance = StyleDictionary.extend(config)
21 |
22 | platforms.forEach((platform) => {
23 | sdInstance.buildPlatform(platform)
24 | })
25 |
26 | console.log('')
27 | console.info(
28 | `${platforms.length} platform${platforms.length > 1 ? 's' : ''} built!`,
29 | )
30 |
--------------------------------------------------------------------------------
/packages/design-tokens/src/constants.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | breakpoints: {
3 | xxs: 'xxs',
4 |
5 | xs: 'xs',
6 |
7 | sm: 'sm',
8 |
9 | md: 'md',
10 |
11 | lg: 'lg',
12 |
13 | xl: 'xl',
14 |
15 | xxl: 'xxl',
16 | },
17 | }
18 |
--------------------------------------------------------------------------------
/packages/design-tokens/src/matchers.js:
--------------------------------------------------------------------------------
1 | // Those matcher are defined to customize transformation of tokens.
2 |
3 | function isIgnored(token) {
4 | return token.original.ignore === true
5 | }
6 |
7 | function isSize(token) {
8 | return token.attributes.category === 'size' || token.original.group === 'size'
9 | }
10 |
11 | function isBreakpointOrRadiusSize(token) {
12 | return (
13 | !isIgnored(token) &&
14 | isSize(token) &&
15 | ['breakpoint', 'radius'].includes(token.attributes.type)
16 | )
17 | }
18 |
19 | function isNotBreakpointNorRadiusSize(token) {
20 | return (
21 | !isIgnored(token) &&
22 | isSize(token) &&
23 | !['breakpoint', 'radius'].includes(token.attributes.type)
24 | )
25 | }
26 |
27 | function isMediaQuery(token) {
28 | return (
29 | (!isIgnored(token) && token.attributes.category === 'mediaQuery') ||
30 | token.original.group === 'mediaQuery'
31 | )
32 | }
33 |
34 | module.exports = {
35 | isBreakpointOrRadiusSize,
36 | isIgnored,
37 | isMediaQuery,
38 | isNotBreakpointNorRadiusSize,
39 | isSize,
40 | }
41 |
--------------------------------------------------------------------------------
/packages/design-tokens/src/tailwindcss/tailwind.config.ts:
--------------------------------------------------------------------------------
1 | import path from 'node:path'
2 |
3 | import type { Config } from 'tailwindcss'
4 |
5 | import tailwindTheme from './tailwind.theme'
6 |
7 | export default {
8 | content: [
9 | './src/**/*.{html,js,ts,jsx,tsx}',
10 | path.join(
11 | path.dirname(require.resolve('@snowball-tech/fractal')),
12 | '**/*.{html,js,ts,jsx,tsx}',
13 | ),
14 | ],
15 |
16 | corePlugins: {
17 | columns: false,
18 | },
19 |
20 | plugins: [
21 | // eslint-disable-next-line @typescript-eslint/no-require-imports
22 | require('@tailwindcss/aspect-ratio'),
23 | // eslint-disable-next-line @typescript-eslint/no-require-imports
24 | require('@tailwindcss/container-queries'),
25 | ],
26 |
27 | theme: tailwindTheme,
28 | } satisfies Config
29 |
--------------------------------------------------------------------------------
/packages/design-tokens/src/transforms.js:
--------------------------------------------------------------------------------
1 | const StyleDictionary = require('style-dictionary')
2 |
3 | const isFinite = require('lodash/fp/isFinite')
4 | const isString = require('lodash/fp/isString')
5 |
6 | const {
7 | isBreakpointOrRadiusSize,
8 | isMediaQuery,
9 | isNotBreakpointNorRadiusSize,
10 | } = require('./matchers')
11 |
12 | StyleDictionary.registerTransform({
13 | matcher: isNotBreakpointNorRadiusSize,
14 | name: 'size/other/pxToRem',
15 | transformer: (token, options) => {
16 | if (isString(token.value) && token.value.endsWith('%')) {
17 | return token.value
18 | }
19 |
20 | const floatValue = Number.parseFloat(token.value)
21 | if (!isFinite(floatValue)) {
22 | return token.value
23 | }
24 |
25 | if (floatValue === 0) {
26 | return '0'
27 | }
28 |
29 | const baseFontSize = (options && options.basePxFontSize) || 16
30 |
31 | return `${floatValue / baseFontSize}rem`
32 | },
33 | type: 'value',
34 | })
35 |
36 | StyleDictionary.registerTransform({
37 | matcher: isBreakpointOrRadiusSize,
38 | name: 'size/breakpoint-radius/px',
39 | transformer: (token) => {
40 | if (isString(token.value) && token.value.endsWith('%')) {
41 | return token.value
42 | }
43 |
44 | const floatValue = Number.parseFloat(token.value)
45 | if (!isFinite(floatValue)) {
46 | return token.value
47 | }
48 |
49 | if (floatValue === 0) {
50 | return '0'
51 | }
52 |
53 | return `${floatValue}px`
54 | },
55 | type: 'value',
56 | })
57 |
58 | StyleDictionary.registerTransform({
59 | matcher: isMediaQuery,
60 | name: 'media-query/quote',
61 | transformer: (token) => `'${token.value}'`,
62 | transitive: true,
63 | type: 'value',
64 | })
65 |
66 | module.exports = {}
67 |
--------------------------------------------------------------------------------
/packages/design-tokens/tokens/border.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | border: {
3 | none: {
4 | comment: 'Disable borders.',
5 |
6 | value: 'none',
7 | },
8 |
9 | 1: {
10 | comment: 'A subtle border.',
11 |
12 | value: '{size.border.1.value} solid {color.border.default.value}',
13 | },
14 | 2: {
15 | comment: 'A more obvious border.',
16 |
17 | value: '{size.border.2.value} solid {color.border.default.value}',
18 | },
19 |
20 | disabled: {
21 | comment:
22 | 'A border to use on disabled elements (e.g. buttons, input, ...).',
23 |
24 | value: '{size.border.1.value} solid {color.border.disabled.value}',
25 | },
26 |
27 | transparent: {
28 | 1: {
29 | comment: 'A transparent 1px border.',
30 |
31 | value: '{size.border.1.value} solid {color.base.transparent.value}',
32 | },
33 | 2: {
34 | comment: 'A transparent 2px border.',
35 |
36 | value: '{size.border.2.value} solid {color.base.transparent.value}',
37 | },
38 | },
39 | },
40 | }
41 |
--------------------------------------------------------------------------------
/packages/design-tokens/tokens/color/background.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | color: {
3 | background: {
4 | body: {
5 | black: {
6 | comment: 'Black Tone 0',
7 | value: '{color.base.black.value}',
8 | },
9 | dark: {
10 | comment: 'Black',
11 | value: '{color.brand.body.dark.value}',
12 | },
13 | default: {
14 | comment: 'Default background color',
15 | value: '{color.brand.body.light.value}',
16 | },
17 | light: {
18 | comment: 'Yellowish White Tone 90',
19 | value: '{color.brand.body.light.value}',
20 | },
21 | primary: {
22 | comment: 'Primary color for background',
23 | value: '{color.brand.primary.value}',
24 | },
25 | secondary: {
26 | comment: 'Secondary color for background',
27 | value: '{color.brand.secondary.value}',
28 | },
29 | white: {
30 | comment: 'White Tone 100',
31 | value: '{color.base.white.value}',
32 | },
33 | },
34 |
35 | disabled: {
36 | comment:
37 | 'Background color to use on most disabled elements (e.g. buttons).',
38 |
39 | value: '{color.base.grey.70.value}',
40 | },
41 | },
42 | },
43 | }
44 |
--------------------------------------------------------------------------------
/packages/design-tokens/tokens/color/base.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | color: {
3 | base: {
4 | black: { comment: 'Black Tone 0', value: '#000000' },
5 | grey: {
6 | 30: { comment: 'Grey Tone 30', value: '#7E7C78' },
7 | 50: { comment: 'Grey Tone 50', value: '#B7B1A6' },
8 | 70: { comment: 'Grey Tone 70', value: '#DDD9D4' },
9 | 90: { comment: 'Grey Tone 90', value: '#F5F1EC' },
10 | },
11 | white: { comment: 'White Tone 100', value: '#FFFFFF' },
12 |
13 | transparent: { comment: 'Transparent', value: 'transparent' },
14 | },
15 | },
16 | }
17 |
--------------------------------------------------------------------------------
/packages/design-tokens/tokens/color/border.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | color: {
3 | border: {
4 | dark: { value: '{color.brand.primary.value}' },
5 | default: { value: '{color.base.black.value}' },
6 | disabled: { value: '{color.base.grey.50.value}' },
7 | light: { value: '{color.base.white.value}' },
8 | primary: { value: '{color.brand.primary.value}' },
9 | 'primary-dark': { value: '{color.brand.primary-light.value}' },
10 | 'primary-light': { value: '{color.brand.primary-dark.value}' },
11 | secondary: { value: '{color.brand.secondary.value}' },
12 | 'secondary-dark': { value: '{color.brand.secondary-dark.value}' },
13 | 'secondary-light': { value: '{color.brand.secondary-light.value}' },
14 | },
15 | },
16 | }
17 |
--------------------------------------------------------------------------------
/packages/design-tokens/tokens/color/brand.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | color: {
3 | brand: {
4 | comment: "Main Snowball's brand colors.",
5 |
6 | body: {
7 | dark: { comment: 'Black', value: '{color.base.black}' },
8 | light: { comment: 'Yellowish White Tone 90', value: '#FFFBF4' },
9 | },
10 |
11 | highlight: {
12 | comment: 'Tone 90',
13 | value: '{color.decorative.pink.90.value}',
14 | },
15 |
16 | primary: { comment: 'Tone 90', value: '#FF8ACD' },
17 | 'primary-dark': { comment: 'Tone 90', value: '#FF8ACD' },
18 | 'primary-light': { comment: 'Tone 90', value: '#FF8ACD' },
19 | secondary: {
20 | comment: 'Black Tone 0',
21 | value: '{color.base.black.value}',
22 | },
23 | 'secondary-dark': {
24 | comment: 'White Tone 100',
25 | value: '{color.base.white.value}',
26 | },
27 | 'secondary-light': {
28 | comment: 'Black Tone 0',
29 | value: '{color.base.black.value}',
30 | },
31 |
32 | separator: {
33 | comment: 'Used for line separators',
34 | value: '{color.base.grey.70.value}',
35 | },
36 | },
37 | },
38 | }
39 |
--------------------------------------------------------------------------------
/packages/design-tokens/tokens/color/decorative.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | color: {
3 | decorative: {
4 | comment: 'Decorative colors used for branding and marketing.',
5 |
6 | blue: {
7 | 50: { comment: 'Blue Tone 50', value: '#8AF1FF' },
8 | 70: { comment: 'Blue Tone 70', value: '#B3F6FF' },
9 | 90: { comment: 'Blue Tone 90', value: '#D6FAFF' },
10 | },
11 | green: {
12 | 50: { comment: 'Green Tone 50', value: '#76F7AE' },
13 | 70: { comment: 'Green Tone 70', value: '#ADFACE' },
14 | 90: { comment: 'Green Tone 90', value: '#CFFCE3' },
15 | },
16 | pink: {
17 | 70: { comment: 'Pink Tone 70', value: '#FFC6E7' },
18 | 90: { comment: 'Pink Tone 90', value: '#FFE2F3' },
19 | },
20 | purple: {
21 | 50: { comment: 'Purple Tone 50', value: '#B37DFF' },
22 | 70: { comment: 'Purple Tone 70', value: '#D9BEFF' },
23 | 90: { comment: 'Purple Tone 90', value: '#F0E5FF' },
24 | },
25 | yellow: {
26 | 50: { comment: 'Yellow Tone 50', value: '#FFE959' },
27 | 70: { comment: 'Yellow Tone 70', value: '#FFF29B' },
28 | 90: { comment: 'Yellow Tone 90', value: '#FFF8C5' },
29 | },
30 | },
31 | },
32 | }
33 |
--------------------------------------------------------------------------------
/packages/design-tokens/tokens/color/feedback.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | color: {
3 | feedback: {
4 | comment:
5 | 'Feedback colors used for danger/error, warning and success states.',
6 |
7 | danger: {
8 | 50: { comment: 'Tone 50', value: '#FF5454' },
9 | 90: { comment: 'Tone 90', value: '#FFD6D6' },
10 | },
11 | error: {
12 | 50: { comment: 'Tone 50', value: '{color.feedback.danger.50.value}' },
13 | 90: { comment: 'Tone 90', value: '{color.feedback.danger.90.value}' },
14 | },
15 | success: {
16 | 50: { comment: 'Tone 50', value: '#3CD39D' },
17 | 90: { comment: 'Tone 90', value: '#CFFCE3' },
18 | },
19 | warning: {
20 | 50: { comment: 'Tone 50', value: '#FF9F69' },
21 | 90: { comment: 'Tone 90', value: '#FFEAD1' },
22 | },
23 | },
24 | },
25 | }
26 |
--------------------------------------------------------------------------------
/packages/design-tokens/tokens/color/stroke.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | color: {
3 | stroke: {
4 | comment: 'Colors for various strokes.',
5 |
6 | separator: {
7 | comment: 'Used for separators',
8 |
9 | value: '{color.base.grey.70.value}',
10 | },
11 | },
12 | },
13 | }
14 |
--------------------------------------------------------------------------------
/packages/design-tokens/tokens/size/border.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | size: {
3 | border: {
4 | 1: { value: 1 },
5 | 2: { value: 2 },
6 | },
7 | },
8 | }
9 |
--------------------------------------------------------------------------------
/packages/design-tokens/tokens/size/radius.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | size: {
3 | radius: {
4 | 0: {
5 | value: 0,
6 | },
7 |
8 | xs: {
9 | value: 4,
10 | },
11 |
12 | s: {
13 | value: 8,
14 | },
15 |
16 | m: {
17 | value: 16,
18 | },
19 |
20 | rounded: {
21 | value: 9999,
22 | },
23 | },
24 | },
25 | }
26 |
--------------------------------------------------------------------------------
/packages/design-tokens/tokens/size/spacing.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | size: {
3 | spacing: {
4 | 0: {
5 | value: 0,
6 | },
7 |
8 | px: {
9 | value: 1,
10 | },
11 |
12 | quarter: {
13 | value: 2,
14 | },
15 |
16 | half: {
17 | value: 4,
18 | },
19 |
20 | 1: {
21 | value: 8,
22 | },
23 |
24 | 2: {
25 | value: 16,
26 | },
27 |
28 | 3: {
29 | value: 24,
30 | },
31 |
32 | 4: {
33 | value: 32,
34 | },
35 |
36 | 5: {
37 | value: 40,
38 | },
39 |
40 | 6: {
41 | value: 48,
42 | },
43 |
44 | 7: {
45 | value: 56,
46 | },
47 |
48 | 8: {
49 | value: 64,
50 | },
51 |
52 | 9: {
53 | value: 72,
54 | },
55 |
56 | 10: {
57 | value: 80,
58 | },
59 |
60 | 11: {
61 | value: 88,
62 | },
63 |
64 | 12: {
65 | value: 96,
66 | },
67 |
68 | 13: {
69 | value: 104,
70 | },
71 |
72 | 14: {
73 | value: 112,
74 | },
75 |
76 | 15: {
77 | value: 120,
78 | },
79 |
80 | 16: {
81 | value: 128,
82 | },
83 |
84 | 17: {
85 | value: 136,
86 | },
87 |
88 | 18: {
89 | value: 144,
90 | },
91 |
92 | 19: {
93 | value: 152,
94 | },
95 |
96 | 20: {
97 | value: 160,
98 | },
99 | },
100 | },
101 | }
102 |
--------------------------------------------------------------------------------
/packages/design-tokens/tokens/style-and-decoration.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | decoration: {
3 | text: {
4 | none: {
5 | comment: 'Display a text without any decoration.',
6 |
7 | value: 'none',
8 | },
9 |
10 | striked: {
11 | comment: 'Display a striked text.',
12 |
13 | value: 'line-through',
14 | },
15 |
16 | underline: {
17 | comment: 'Display an underlined text.',
18 |
19 | value: 'underline',
20 | },
21 |
22 | wavy: {
23 | comment: 'Display a text with a wavy underline.',
24 |
25 | value: 'wavy',
26 | },
27 | },
28 | },
29 |
30 | style: {
31 | text: {
32 | default: {
33 | comment: 'Display a text normally.',
34 |
35 | value: 'normal',
36 | },
37 |
38 | italic: {
39 | comment: 'Display a text in italic.',
40 |
41 | value: 'italic',
42 | },
43 |
44 | placeholder: {
45 | comment: 'Text style for placeholders.',
46 |
47 | value: '{style.text.default.value}',
48 | },
49 | },
50 | },
51 | }
52 |
--------------------------------------------------------------------------------
/packages/design-tokens/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "composite": false,
5 | "noEmit": false
6 | },
7 | "include": ["src/**/*.ts"],
8 | "files": [],
9 | "references": []
10 | }
11 |
--------------------------------------------------------------------------------
/packages/design-tokens/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "baseUrl": ".",
5 | "isolatedModules": true,
6 | "lib": ["DOM", "DOM.Iterable", "ESNext"],
7 | "module": "ESNext",
8 | "moduleResolution": "bundler",
9 | "outDir": "./dist",
10 | "paths": {
11 | "@/*": ["./src/*"]
12 | },
13 | "rootDir": "./src",
14 | "target": "ESNext",
15 | "useDefineForClassFields": true
16 | },
17 | "include": ["src/**/*.ts"],
18 | "files": [],
19 | "references": []
20 | }
21 |
--------------------------------------------------------------------------------
/packages/fractal/.gitignore:
--------------------------------------------------------------------------------
1 | .vercel
2 | .env*.local
3 | dist
4 | storybook-static
5 | vite.config.ts.timestamp*
6 |
7 | # Fonts are not open-source
8 | public/fonts/PolySans*
9 |
--------------------------------------------------------------------------------
/packages/fractal/.prettierrc.cjs:
--------------------------------------------------------------------------------
1 | module.exports = require('@snowball-tech/prettier-config/.prettierrc-tailwind')
2 |
--------------------------------------------------------------------------------
/packages/fractal/.storybook/DocumentationTemplate.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | Controls,
3 | Description,
4 | Meta,
5 | Primary,
6 | Subtitle,
7 | Title,
8 | } from '@storybook/blocks'
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | ---
19 |
20 |
21 |
22 | ## Props
23 |
24 | The component accepts the following props:
25 |
26 |
27 |
--------------------------------------------------------------------------------
/packages/fractal/.storybook/manager.ts:
--------------------------------------------------------------------------------
1 | import { addons } from '@storybook/manager-api'
2 |
3 | import fractalTheme from './theme'
4 |
5 | addons.setConfig({
6 | sidebar: {
7 | filters: {
8 | patterns: (item) => !item.name.startsWith('Interactive'),
9 | },
10 | },
11 | theme: fractalTheme,
12 | })
13 |
--------------------------------------------------------------------------------
/packages/fractal/.storybook/preview.tsx:
--------------------------------------------------------------------------------
1 | import type { Preview } from '@storybook/react'
2 |
3 | import {
4 | ColorBaseBlack,
5 | ColorBaseWhite,
6 | } from '@snowball-tech/design-tokens/dist/web/typescript/design-tokens'
7 | import isChromatic from 'chromatic/isChromatic'
8 |
9 | import DocumentationTemplate from './DocumentationTemplate.mdx'
10 | import fractalTheme from './theme'
11 |
12 | import '../src/styles/global.css'
13 |
14 | const preview: Preview = {
15 | decorators: isChromatic()
16 | ? [(storyFunction) => {storyFunction()}
]
17 | : [],
18 |
19 | parameters: {
20 | actions: { argTypesRegex: '^on[A-Z].*' },
21 |
22 | controls: {
23 | expanded: true,
24 | hideNoControlsWarning: true,
25 | matchers: {
26 | color: /(background|color)$/i,
27 | date: /Date$/,
28 | },
29 | },
30 |
31 | docs: {
32 | argTypes: {
33 | sort: 'requiredFirst',
34 | },
35 | controls: {
36 | sort: 'requiredFirst',
37 | },
38 | page: DocumentationTemplate,
39 | theme: {
40 | ...fractalTheme,
41 |
42 | textColor: ColorBaseBlack,
43 | textInverseColor: ColorBaseWhite,
44 | },
45 | },
46 |
47 | options: {
48 | storySort: {
49 | method: 'alphabetical',
50 | order: [
51 | 'Fractal',
52 | 'Atoms',
53 | 'Molecules',
54 | 'Organisms',
55 | 'Templates',
56 | 'Pages',
57 | '[Work In Progress]',
58 | ],
59 | },
60 | },
61 |
62 | pseudo: {
63 | rootSelector: 'body',
64 | },
65 |
66 | tags: ['autodocs'],
67 | },
68 | }
69 |
70 | export default preview
71 |
--------------------------------------------------------------------------------
/packages/fractal/.storybook/theme.ts:
--------------------------------------------------------------------------------
1 | import type { ThemeVars } from '@storybook/theming'
2 |
3 | import {
4 | ColorBaseBlack as Black,
5 | ColorBackgroundBodyLight as ContentBackgroundColor,
6 | FontFamilyNormal as FontFamily,
7 | ColorBrandPrimary as PrimaryColor,
8 | SizeRadiusM as Radius,
9 | ColorBrandSecondary as SecondaryColor,
10 | ColorBaseWhite as White,
11 | } from '@snowball-tech/design-tokens/dist/web/typescript/design-tokens'
12 | import { create } from '@storybook/theming/create'
13 |
14 | const SidebarBackgroundColor = Black
15 | const TopbarBackgroundColor = PrimaryColor
16 |
17 | const theme: ThemeVars = create({
18 | base: 'light',
19 |
20 | brandImage: '/images/logo_pink_white.png',
21 | brandTarget: '_blank',
22 | brandTitle: 'Fractal',
23 | brandUrl: 'https://snowball.xyz',
24 |
25 | appBg: SidebarBackgroundColor,
26 | appContentBg: ContentBackgroundColor,
27 | barBg: TopbarBackgroundColor,
28 | fontBase: FontFamily,
29 |
30 | barTextColor: Black,
31 | textColor: Black,
32 | textInverseColor: White,
33 |
34 | appBorderColor: Black,
35 | appBorderRadius: Number.parseInt(Radius, 10),
36 |
37 | colorPrimary: PrimaryColor,
38 | colorSecondary: SecondaryColor,
39 | })
40 |
41 | export default theme
42 |
--------------------------------------------------------------------------------
/packages/fractal/eslint.config.mjs:
--------------------------------------------------------------------------------
1 | // eslint-disable-next-line no-restricted-exports, import/no-relative-packages
2 | export { default } from '../../eslint.config.mjs'
3 |
--------------------------------------------------------------------------------
/packages/fractal/global.d.ts:
--------------------------------------------------------------------------------
1 | declare module '@snowball-tech/design-tokens/dist/web/typescript/constants' {
2 | export const breakpoints: {
3 | xxs: 'xxs'
4 |
5 | xs: 'xs'
6 |
7 | sm: 'sm'
8 |
9 | md: 'md'
10 |
11 | lg: 'lg'
12 |
13 | xl: 'xl'
14 |
15 | xxl: 'xxl'
16 | }
17 | }
18 |
19 | declare namespace JSX {
20 | interface IntrinsicElements {
21 | 'em-emoji': {
22 | fallback?: string
23 | id?: string
24 | native?: string
25 | set?: 'apple' | 'facebook' | 'google' | 'native' | 'twitter'
26 | shortcodes?: string
27 | size?: number | string
28 | skin?: number | string
29 | } & React.DetailedHTMLProps, HTMLElement>
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/packages/fractal/index.ts:
--------------------------------------------------------------------------------
1 | export * from './src/components/index.js'
2 |
--------------------------------------------------------------------------------
/packages/fractal/postcss.config.cjs:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | 'postcss-import': {},
4 |
5 | tailwindcss: {},
6 |
7 | ...(process.env.NODE_ENV === 'development'
8 | ? {}
9 | : { '@csstools/postcss-cascade-layers': { onImportLayerRule: 'warn' } }),
10 |
11 | 'postcss-preset-env': {
12 | autoprefixer: {
13 | flexbox: 'no-2009',
14 | },
15 | features: {
16 | 'custom-properties': false,
17 | },
18 | stage: 3,
19 | },
20 |
21 | 'postcss-flexbugs-fixes': {},
22 |
23 | 'postcss-logical': {},
24 | },
25 | }
26 |
--------------------------------------------------------------------------------
/packages/fractal/public/android-chrome-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/snowball-tech/fractal/937cb391854d855c58a5421ad81bb989814f5c2a/packages/fractal/public/android-chrome-192x192.png
--------------------------------------------------------------------------------
/packages/fractal/public/android-chrome-384x384.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/snowball-tech/fractal/937cb391854d855c58a5421ad81bb989814f5c2a/packages/fractal/public/android-chrome-384x384.png
--------------------------------------------------------------------------------
/packages/fractal/public/apple-touch-icon-120x120.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/snowball-tech/fractal/937cb391854d855c58a5421ad81bb989814f5c2a/packages/fractal/public/apple-touch-icon-120x120.png
--------------------------------------------------------------------------------
/packages/fractal/public/apple-touch-icon-152x152.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/snowball-tech/fractal/937cb391854d855c58a5421ad81bb989814f5c2a/packages/fractal/public/apple-touch-icon-152x152.png
--------------------------------------------------------------------------------
/packages/fractal/public/apple-touch-icon-180x180.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/snowball-tech/fractal/937cb391854d855c58a5421ad81bb989814f5c2a/packages/fractal/public/apple-touch-icon-180x180.png
--------------------------------------------------------------------------------
/packages/fractal/public/apple-touch-icon-60x60.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/snowball-tech/fractal/937cb391854d855c58a5421ad81bb989814f5c2a/packages/fractal/public/apple-touch-icon-60x60.png
--------------------------------------------------------------------------------
/packages/fractal/public/apple-touch-icon-76x76.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/snowball-tech/fractal/937cb391854d855c58a5421ad81bb989814f5c2a/packages/fractal/public/apple-touch-icon-76x76.png
--------------------------------------------------------------------------------
/packages/fractal/public/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/snowball-tech/fractal/937cb391854d855c58a5421ad81bb989814f5c2a/packages/fractal/public/apple-touch-icon.png
--------------------------------------------------------------------------------
/packages/fractal/public/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/snowball-tech/fractal/937cb391854d855c58a5421ad81bb989814f5c2a/packages/fractal/public/favicon-16x16.png
--------------------------------------------------------------------------------
/packages/fractal/public/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/snowball-tech/fractal/937cb391854d855c58a5421ad81bb989814f5c2a/packages/fractal/public/favicon-32x32.png
--------------------------------------------------------------------------------
/packages/fractal/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/snowball-tech/fractal/937cb391854d855c58a5421ad81bb989814f5c2a/packages/fractal/public/favicon.ico
--------------------------------------------------------------------------------
/packages/fractal/public/images/cover_fractal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/snowball-tech/fractal/937cb391854d855c58a5421ad81bb989814f5c2a/packages/fractal/public/images/cover_fractal.png
--------------------------------------------------------------------------------
/packages/fractal/public/images/cover_fractal_old.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/snowball-tech/fractal/937cb391854d855c58a5421ad81bb989814f5c2a/packages/fractal/public/images/cover_fractal_old.png
--------------------------------------------------------------------------------
/packages/fractal/public/images/logo_fractal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/snowball-tech/fractal/937cb391854d855c58a5421ad81bb989814f5c2a/packages/fractal/public/images/logo_fractal.png
--------------------------------------------------------------------------------
/packages/fractal/public/images/logo_pink_black.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/snowball-tech/fractal/937cb391854d855c58a5421ad81bb989814f5c2a/packages/fractal/public/images/logo_pink_black.png
--------------------------------------------------------------------------------
/packages/fractal/public/images/logo_pink_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/snowball-tech/fractal/937cb391854d855c58a5421ad81bb989814f5c2a/packages/fractal/public/images/logo_pink_white.png
--------------------------------------------------------------------------------
/packages/fractal/public/site.webmanifest:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Fractal",
3 | "short_name": "Fractal",
4 | "icons": [
5 | {
6 | "src": "/android-chrome-192x192.png?v=1",
7 | "sizes": "192x192",
8 | "type": "image/png"
9 | },
10 | {
11 | "src": "/android-chrome-384x384.png?v=1",
12 | "sizes": "384x384",
13 | "type": "image/png"
14 | }
15 | ],
16 | "theme_color": "#ffffff",
17 | "background_color": "#ffffff",
18 | "start_url": "https://fractal.snowball.xyz",
19 | "display": "standalone"
20 | }
21 |
--------------------------------------------------------------------------------
/packages/fractal/scripts/build-stats.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # Enable globstar expansion to make glob path below work.
4 | shopt -s globstar
5 | # And also enable extended glob syntax to exclude some files below.
6 | shopt -s extglob
7 |
8 | # shellcheck disable=SC2181
9 |
10 | # Compute and display stats about the built Fractal package
11 |
12 | # shellcheck disable=SC1090
13 | source "$(dirname "$0")/../../../scripts/colors.sh"
14 |
15 | if [ ! -d "./dist" ]; then
16 | bold_error "The 'dist' directory does not exist. Please build the Fractal package first:"
17 |
18 | echo ""
19 | echo -e "\t$(reverse "yarn build")"
20 | echo ""
21 |
22 | exit 1
23 | fi
24 |
25 | # Total size
26 | totalSize=$(du -sh ./dist | awk '{print $1}')
27 | jsSize=$(du -ch ./dist/**/!(chunk).js | grep total$ | awk '{print $1}')
28 | cssSize=$(du -ch ./dist/**/*.css | grep total$ | awk '{print $1}')
29 | mapsSize=$(du -ch ./dist/**/*.map | grep total$ | awk '{print $1}')
30 | typesSize=$(du -ch ./dist/**/*.d.ts | grep total$ | awk '{print $1}')
31 | chunksSize=$(du -ch ./dist/*.js | grep total$ | awk '{print $1}')
32 | bundleSize=$(du -ch ./dist/*.js ./dist/*.css | grep total$ | awk '{print $1}')
33 |
34 | echo ""
35 | echo -e "$(bold "Total size"): $(display_number "$totalSize")"
36 | echo -e "\t$(underline "Package JS files"): $(display_number "$jsSize")"
37 | echo -e "\t$(underline "TypeScript typings"): $(display_number "$typesSize")"
38 | echo -e "\t$(underline "Maps"): $(display_number "$mapsSize")"
39 | echo ""
40 |
41 | echo -e "$(bold "Bundle size"): $(display_number "$bundleSize")"
42 | echo -e "\t$(underline "Chunks"): $(display_number "$chunksSize")"
43 | echo -e "\t$(underline "CSS"): $(display_number "$cssSize")"
44 | echo ""
45 |
--------------------------------------------------------------------------------
/packages/fractal/scripts/transform-icons-imports.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | import fs from 'fs-extra'
4 | import { globSync } from 'glob'
5 |
6 | // eslint-disable-next-line import/extensions
7 | import _ from 'lodash/fp.js'
8 |
9 | function kebabToPascalCase(string_) {
10 | return string_
11 | .split('-')
12 | .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
13 | .join('')
14 | }
15 |
16 | // Fonction pour transformer les imports
17 | function transformImports(filePath) {
18 | const content = fs.readFileSync(filePath, 'utf8')
19 | const newContent = content.replaceAll(
20 | /import\s+(\w+)\s+from\s+'@iconscout\/react-un(?:icons\/){2}uil-([\w-]+)'/g,
21 | (match, p1, p2) => {
22 | const pascalCaseName = kebabToPascalCase(p2)
23 |
24 | return `import { Uil${pascalCaseName} as ${p1} } from '@tooni/iconscout-unicons-react'`
25 | },
26 | )
27 |
28 | if (newContent !== content) {
29 | fs.writeFileSync(filePath, newContent, 'utf8')
30 | console.log(`Updated imports in: ${filePath}`)
31 | }
32 | }
33 |
34 | try {
35 | const files = globSync(`src/**/*.tsx`)
36 |
37 | if (_.isEmpty(files)) {
38 | console.log('No file found.')
39 | } else {
40 | files.forEach((filePath) => transformImports(filePath))
41 | console.log('All imports have been updated.')
42 | }
43 | } catch (error) {
44 | console.error('Unable to find TSX file using icons:', error)
45 | }
46 |
--------------------------------------------------------------------------------
/packages/fractal/src/ThemeProvider.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { type ReactNode, createContext } from 'react'
4 |
5 | import { DEFAULT_THEME, Themes } from './constants'
6 |
7 | export const ThemeContext = createContext<{
8 | theme: Themes
9 | }>({ theme: DEFAULT_THEME })
10 |
11 | type Props = {
12 | children: ReactNode
13 | theme: Themes
14 | }
15 | export default function ThemeProvider({
16 | children,
17 | theme = DEFAULT_THEME,
18 | }: Props) {
19 | return (
20 | {children}
21 | )
22 | }
23 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Autocomplete/Autocomplete.constants.ts:
--------------------------------------------------------------------------------
1 | export const GROUP_NAME = 'autocomplete'
2 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Autocomplete/Autocomplete.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ArgTypes,
3 | Controls,
4 | Description,
5 | Meta,
6 | Primary,
7 | Subtitle,
8 | Title,
9 | } from '@storybook/blocks'
10 |
11 | import * as AutocompleteStories from './Autocomplete.stories'
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | ---
22 |
23 | ## Props
24 |
25 | On top of all the props, attributes and event handler you can set on a
26 | `` component (and thus a `` element), the component accepts
27 | the following props:
28 |
29 |
30 |
31 | ## Playground
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Autocomplete/AutocompleteEmpty.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ArgTypes,
3 | Controls,
4 | Description,
5 | Meta,
6 | Primary,
7 | Subtitle,
8 | Title,
9 | } from '@storybook/blocks'
10 |
11 | import * as AutocompleteEmptyStories from './AutocompleteEmpty.stories'
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | ---
22 |
23 | ## Props
24 |
25 | On top of all the props, attributes and event handler you can set on a
26 | `` element, the component accepts the following props:
27 |
28 |
29 |
30 | ## Playground
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Autocomplete/AutocompleteEmpty.stories.tsx:
--------------------------------------------------------------------------------
1 | import type { Meta, StoryObj } from '@storybook/react'
2 |
3 | import type { ComponentProps } from 'react'
4 |
5 | import Autocomplete from './Autocomplete'
6 | import AutocompleteEmpty from './AutocompleteEmpty'
7 |
8 | type AutocompleteEmptyProps = ComponentProps
9 |
10 | const meta: Meta = {
11 | args: {
12 | children: 'No results! Sorry about that!',
13 | },
14 | argTypes: {
15 | children: {
16 | control: 'text',
17 | },
18 | },
19 | component: AutocompleteEmpty,
20 | parameters: {
21 | chromatic: { delay: 2000 },
22 | },
23 |
24 | title: 'Molecules/Autocomplete/AutocompleteEmpty',
25 | } satisfies Meta
26 |
27 | export default meta
28 | type Story = StoryObj
29 |
30 | export const Playground: Story = {
31 | render: ({ children }) => (
32 |
33 |
34 | {children}
35 |
36 |
37 | ),
38 | }
39 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Autocomplete/AutocompleteEmpty.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import * as RxDropdownMenu from '@radix-ui/react-dropdown-menu'
4 |
5 | import isEmpty from 'lodash/fp/isEmpty'
6 | import omit from 'lodash/fp/omit'
7 |
8 | import { Typography } from '@/components/Typography/Typography'
9 | import { PREFIX } from '@/constants'
10 | import { cn } from '@/styles/helpers'
11 |
12 | import type { AutocompleteEmptyProps } from './Autocomplete.types'
13 |
14 | import { GROUP_NAME } from './Autocomplete.constants'
15 |
16 | /**
17 | * `AutocompleteEmpty` component is used to display an empty state inside of the
18 | * dropdown of an `Autocomplete` component.
19 | *
20 | * See https://www.radix-ui.com/primitives/docs/components/dropdown-menu#item
21 | * for more information.
22 | */
23 | export const AutocompleteEmpty = ({
24 | children,
25 | label,
26 | ...props
27 | }: AutocompleteEmptyProps) => {
28 | const hasChildren = Boolean(children)
29 | if (!hasChildren && isEmpty(label)) {
30 | console.warn(
31 | 'You must provide a `label` or `children` to the `AutocompleteEmpty` component',
32 | )
33 | }
34 |
35 | return (
36 | event.preventDefault()}
45 | {...omit(['className', 'disabled', 'onSelect'], props)}
46 | >
47 | {hasChildren ? children : label}
48 |
49 | )
50 | }
51 | AutocompleteEmpty.displayName = 'AutocompleteEmpty'
52 |
53 | export default AutocompleteEmpty
54 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Autocomplete/AutocompleteItem.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ArgTypes,
3 | Controls,
4 | Description,
5 | Meta,
6 | Primary,
7 | Subtitle,
8 | Title,
9 | } from '@storybook/blocks'
10 |
11 | import * as AutocompleteItemStories from './AutocompleteItem.stories'
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | ---
22 |
23 | ## Props
24 |
25 | On top of all the props, attributes and event handler you can set on a
26 | `` component (and thus a `` element), the component
27 | accepts the following props:
28 |
29 |
30 |
31 | ## Playground
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Autocomplete/AutocompleteItem.stories.tsx:
--------------------------------------------------------------------------------
1 | import type { Meta, StoryObj } from '@storybook/react'
2 |
3 | import { action } from '@storybook/addon-actions'
4 |
5 | import type { ComponentProps } from 'react'
6 |
7 | import AutocompleteItem from '@/components/Dropdown/DropdownItem'
8 |
9 | import Autocomplete from './Autocomplete'
10 |
11 | type AutocompleteItemProps = ComponentProps
12 |
13 | const meta: Meta = {
14 | args: {
15 | disabled: false,
16 | label: 'Jar Jar Binks',
17 | value: 'jar-jar-binks',
18 | },
19 | component: AutocompleteItem,
20 | parameters: {
21 | chromatic: { delay: 2000 },
22 | },
23 |
24 | title: 'Molecules/Autocomplete/AutocompleteItem',
25 | } satisfies Meta
26 |
27 | export default meta
28 | type Story = StoryObj
29 |
30 | export const Playground: Story = {
31 | render: ({ disabled = false, label = '', value = '' }) => (
32 |
40 | ),
41 | }
42 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Autocomplete/AutocompleteItemGroup.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ArgTypes,
3 | Controls,
4 | Description,
5 | Meta,
6 | Primary,
7 | Subtitle,
8 | Title,
9 | } from '@storybook/blocks'
10 |
11 | import * as AutocompleteItemGroupStories from './AutocompleteItemGroup.stories'
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | ---
22 |
23 | ## Props
24 |
25 | On top of all the props, attributes and event handler you can set on a
26 | `` component (and thus a `` element), the component
27 | accepts the following props:
28 |
29 |
30 |
31 | ## Playground
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Autocomplete/AutocompleteItemSeparator.mdx:
--------------------------------------------------------------------------------
1 | import { Description, Meta, Primary, Subtitle, Title } from '@storybook/blocks'
2 |
3 | import * as AutocompleteItemSeparatortories from './AutocompleteItemSeparator.stories'
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | ---
14 |
15 | ## Props
16 |
17 | You can set for this component all the props, attributes and event handler you
18 | can set on a `` component (and thus a ``
19 | element).
20 |
21 | ## Playground
22 |
23 |
24 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Autocomplete/AutocompleteItemSeparator.stories.tsx:
--------------------------------------------------------------------------------
1 | import type { Meta, StoryObj } from '@storybook/react'
2 |
3 | import { action } from '@storybook/addon-actions'
4 |
5 | import type { ComponentProps } from 'react'
6 |
7 | import AutocompleteItem from '@/components/Dropdown/DropdownItem'
8 | import AutocompleteItemSeparator from '@/components/Dropdown/DropdownItemSeparator'
9 |
10 | import Autocomplete from './Autocomplete'
11 |
12 | type AutocompleteItemSeparatorProps = ComponentProps<
13 | typeof AutocompleteItemSeparator
14 | >
15 |
16 | const meta: Meta = {
17 | component: AutocompleteItemSeparator,
18 | parameters: {
19 | chromatic: { delay: 2000 },
20 | },
21 |
22 | title: 'Molecules/Autocomplete/AutocompleteItemSeparator',
23 | } satisfies Meta
24 |
25 | export default meta
26 | type Story = StoryObj
27 |
28 | export const Playground: Story = {
29 | render: () => (
30 |
31 |
35 |
36 |
37 |
38 |
39 |
40 | ),
41 | }
42 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Autocomplete/AutocompleteLoading.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ArgTypes,
3 | Controls,
4 | Description,
5 | Meta,
6 | Primary,
7 | Subtitle,
8 | Title,
9 | } from '@storybook/blocks'
10 |
11 | import * as AutocompleteLoadingStories from './AutocompleteLoading.stories'
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | ---
22 |
23 | ## Props
24 |
25 | On top of all the props, attributes and event handler you can set on a
26 | `` element, the component accepts the following props:
27 |
28 |
29 |
30 | ## Playground
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Autocomplete/AutocompleteLoading.stories.tsx:
--------------------------------------------------------------------------------
1 | import type { Meta, StoryObj } from '@storybook/react'
2 |
3 | import {
4 | UilMessage as SendIcon,
5 | UilEnvelopeStar as StarIcon,
6 | } from '@tooni/iconscout-unicons-react'
7 |
8 | import type { ComponentProps } from 'react'
9 |
10 | import Autocomplete from './Autocomplete'
11 | import AutocompleteLoading from './AutocompleteLoading'
12 |
13 | type AutocompleteLoadingProps = ComponentProps
14 |
15 | const meta: Meta = {
16 | args: {
17 | children: 'Loading... please wait!',
18 | icon: 'Default',
19 | spin: true,
20 | },
21 | argTypes: {
22 | children: {
23 | control: 'text',
24 | },
25 | icon: {
26 | mapping: {
27 | Default: true,
28 | None: false,
29 | Send: ,
30 | Star: ,
31 | },
32 | options: ['Default', 'None', 'Send', 'Star'],
33 | table: { type: { summary: 'ReactNode | boolean' } },
34 | },
35 | },
36 | component: AutocompleteLoading,
37 | parameters: {
38 | chromatic: { delay: 2000 },
39 | },
40 |
41 | title: 'Molecules/Autocomplete/AutocompleteLoading',
42 | } satisfies Meta
43 |
44 | export default meta
45 | type Story = StoryObj
46 |
47 | export const Playground: Story = {
48 | render: ({ children, icon, spin = false }) => (
49 |
50 |
51 |
52 | {children}
53 |
54 |
55 |
56 | ),
57 | }
58 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Autocomplete/index.ts:
--------------------------------------------------------------------------------
1 | export { default as AutocompleteItem } from '../Dropdown/DropdownItem.js'
2 | export { default as AutocompleteItemGroup } from '../Dropdown/DropdownItemGroup.js'
3 | export { default as AutocompleteItemSeparator } from '../Dropdown/DropdownItemSeparator.js'
4 | export { default as Autocomplete } from './Autocomplete.js'
5 | export type {
6 | AutocompleteEmptyProps,
7 | AutocompleteItemGroupProps,
8 | AutocompleteLoadingProps,
9 | AutocompleteProps,
10 | CombinedRefs as AutocompleteRefs,
11 | } from './Autocomplete.types.js'
12 | export { default as AutocompleteEmpty } from './AutocompleteEmpty.js'
13 | export { default as AutocompleteLoading } from './AutocompleteLoading.js'
14 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Avatar/Avatar.constants.ts:
--------------------------------------------------------------------------------
1 | import { Variants as TypographyVariants } from '@/components/Typography/Typography.constants'
2 |
3 | export const GROUP_NAME = 'avatar'
4 |
5 | export enum Sizes {
6 | // Small.
7 | S = 's',
8 |
9 | // Medium.
10 | M = 'm',
11 |
12 | // Large.
13 | L = 'l',
14 |
15 | // Extra large.
16 | XL = 'xl',
17 |
18 | // Fluid.
19 | Fluid = 'fluid',
20 | }
21 |
22 | export const DEFAULT_SIZE = Sizes.M
23 |
24 | export const sizeToTypographyVariant: Record = {
25 | [Sizes.S]: TypographyVariants.CaptionBold,
26 |
27 | [Sizes.M]: TypographyVariants.CaptionBold,
28 |
29 | [Sizes.L]: TypographyVariants.Body1Bold,
30 |
31 | [Sizes.XL]: TypographyVariants.Heading4,
32 |
33 | [Sizes.Fluid]: TypographyVariants.CaptionBold,
34 | }
35 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Avatar/Avatar.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ArgTypes,
3 | Controls,
4 | Description,
5 | Meta,
6 | Primary,
7 | Stories,
8 | Subtitle,
9 | Title,
10 | } from '@storybook/blocks'
11 |
12 | import * as AvatarStories from './Avatar.stories'
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | ---
23 |
24 | ## Props
25 |
26 | On top of all the props, attributes and event handler you can set on a
27 | `` element, the component accepts the following props:
28 |
29 |
30 |
31 |
32 |
33 | ## Playground
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Avatar/Avatar.types.ts:
--------------------------------------------------------------------------------
1 | import type { AllHTMLAttributes, ReactNode } from 'react'
2 |
3 | import { Sizes } from './Avatar.constants'
4 |
5 | export interface AvatarProps
6 | extends Omit, 'size'> {
7 | /**
8 | * The content of the dropdown menu of the avatar (if you want one).
9 | *
10 | * For the best result, please use the `DropdownItem`, `DropdownItemGroup`,
11 | * `DropdownItemSeparator`, `SubDropdown` or `DropdownRadioGroup` components.
12 | */
13 | children?: ReactNode
14 | /** Indicates if the avatar menu dropdown is disabled. */
15 | disabled?: boolean
16 | /** The URL of the image to display as the avatar. */
17 | imageUrl?: string
18 | /** The name of the person to display as the avatar. */
19 | name?: string
20 | /** The wanted size of the loader. */
21 | size?: `${Sizes}`
22 | }
23 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Avatar/index.ts:
--------------------------------------------------------------------------------
1 | export {
2 | Sizes as AvatarSizes,
3 | sizeToTypographyVariant as avatarSizeToTypographyVariant,
4 | DEFAULT_SIZE as DEFAULT_AVATAR_SIZE,
5 | } from './Avatar.constants.js'
6 | export { default as Avatar } from './Avatar.js'
7 | export type { AvatarProps } from './Avatar.types.js'
8 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Badge/Badge.constants.ts:
--------------------------------------------------------------------------------
1 | export const GROUP_NAME = 'badge'
2 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Badge/Badge.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ArgTypes,
3 | Controls,
4 | Description,
5 | Meta,
6 | Primary,
7 | Stories,
8 | Subtitle,
9 | Title,
10 | } from '@storybook/blocks'
11 |
12 | import * as BadgeStories from './Badge.stories'
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | ---
23 |
24 | ## Props
25 |
26 | On top of all the props, attributes and event handler you can set on a
27 | `` element, the component accepts the following props:
28 |
29 |
30 |
31 |
32 |
33 | ## Playground
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Badge/Badge.stories.tsx:
--------------------------------------------------------------------------------
1 | import type { Meta, StoryObj } from '@storybook/react'
2 |
3 | import type { ComponentProps } from 'react'
4 |
5 | import { Badge } from '.'
6 |
7 | type BadgeProps = ComponentProps
8 |
9 | const perVariantStoriesParameters = {
10 | controls: {
11 | include: ['count, limit = 99'],
12 | },
13 | }
14 |
15 | const meta = {
16 | args: {
17 | count: undefined,
18 | limit: 99,
19 | },
20 | argTypes: {
21 | count: { control: 'number' },
22 | limit: { control: 'number' },
23 | },
24 | component: Badge,
25 | parameters: {
26 | docs: {
27 | subtitle:
28 | "🎈 You may notice one is missing. It's my Assisting the Elderly badge. - Russel - Up",
29 | },
30 | },
31 |
32 | title: 'Molecules/Badge',
33 | } satisfies Meta
34 |
35 | export default meta
36 | type Story = StoryObj
37 |
38 | export const Playground: Story = {}
39 |
40 | export const Badges: Story = {
41 | parameters: { ...perVariantStoriesParameters },
42 | render: () => (
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 | ),
57 | }
58 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Badge/Badge.tsx:
--------------------------------------------------------------------------------
1 | import isEmpty from 'lodash/fp/isEmpty'
2 | import isInteger from 'lodash/fp/isInteger'
3 | import isNil from 'lodash/fp/isNil'
4 | import isNumber from 'lodash/fp/isNumber'
5 | import omit from 'lodash/fp/omit'
6 |
7 | import { Typography } from '@/components/Typography/Typography'
8 | import { PREFIX } from '@/constants'
9 | import { cn } from '@/styles/helpers'
10 |
11 | import type { BadgeProps } from './Badge.types'
12 |
13 | import { GROUP_NAME } from './Badge.constants'
14 |
15 | /**
16 | * `Badge` component displays a number in a small colored bubble.
17 | */
18 | export const Badge = ({ count, label, limit = 99, ...props }: BadgeProps) => {
19 | let actualCount = isNumber(count) && isInteger(count) ? `${count}` : ''
20 | if (
21 | isNumber(limit) &&
22 | limit > 0 &&
23 | !isEmpty(actualCount) &&
24 | (count ?? 0) > limit
25 | ) {
26 | actualCount = `+${limit}`
27 | }
28 |
29 | return (
30 |
45 | {actualCount}
46 |
47 | )
48 | }
49 | Badge.displayName = 'Badge'
50 |
51 | export default Badge
52 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Badge/Badge.types.ts:
--------------------------------------------------------------------------------
1 | import type { AllHTMLAttributes } from 'react'
2 |
3 | export interface BadgeProps extends AllHTMLAttributes {
4 | /** The number to display in the badge. */
5 | count?: number | undefined
6 | /**
7 | * The accessible label of the badge.
8 | *
9 | * If provided, this will be used as the `aria-label` and the `title` of the
10 | * badge.
11 | */
12 | label?: string
13 | /** The number above which we will display "+xx" */
14 | limit?: number | undefined
15 | }
16 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Badge/index.ts:
--------------------------------------------------------------------------------
1 | export { default as Badge } from './Badge.js'
2 | export type { BadgeProps } from './Badge.types.js'
3 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Button/Button.constants.ts:
--------------------------------------------------------------------------------
1 | export const GROUP_NAME = 'button'
2 |
3 | export enum Variants {
4 | Display = 'display',
5 | Primary = 'primary',
6 | Secondary = 'secondary',
7 | Text = 'text',
8 | }
9 |
10 | export const DEFAULT_VARIANT = Variants.Primary
11 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Button/Button.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ArgTypes,
3 | Controls,
4 | Description,
5 | Meta,
6 | Primary,
7 | Stories,
8 | Subtitle,
9 | Title,
10 | } from '@storybook/blocks'
11 |
12 | import * as ButtonStories from './Button.stories'
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | ---
23 |
24 | ## Props
25 |
26 | On top of all the props, attributes and event handler you can set on a
27 | `` (or a `` if you give an `href`) element, the component accepts
28 | the following props:
29 |
30 |
31 |
32 |
33 |
34 | ## Playground
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Button/index.ts:
--------------------------------------------------------------------------------
1 | export {
2 | Variants as ButtonVariants,
3 | DEFAULT_VARIANT as DEFAULT_BUTTON_VARIANT,
4 | } from './Button.constants.js'
5 | export {
6 | default as Button,
7 | variantDisabledClassNames as buttonDisabledClassNames,
8 | variantDisabledStyles as buttonDisabledStyles,
9 | variantClassNames as buttonVariantClassNames,
10 | variantStyles as buttonVariantStyles,
11 | } from './Button.js'
12 | export type { ButtonProps } from './Button.types.js'
13 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Card/Card.constants.ts:
--------------------------------------------------------------------------------
1 | export const GROUP_NAME = 'card'
2 |
3 | export enum Colors {
4 | Blue = 'blue',
5 | Error = 'error',
6 | Green = 'green',
7 | Pink = 'pink',
8 | Purple = 'purple',
9 | Success = 'success',
10 | Warning = 'warning',
11 | Yellow = 'yellow',
12 | }
13 |
14 | export const DEFAULT_COLOR = Colors.Pink
15 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Card/Card.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ArgTypes,
3 | Controls,
4 | Description,
5 | Meta,
6 | Primary,
7 | Stories,
8 | Subtitle,
9 | Title,
10 | } from '@storybook/blocks'
11 |
12 | import * as CardStories from './Card.stories'
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | ---
23 |
24 | ## Props
25 |
26 | On top of all the props, attributes and event handler you can set on a
27 | `` element, component accepts the following props:
28 |
29 |
30 |
31 |
32 |
33 | ## Playground
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Card/Card.types.ts:
--------------------------------------------------------------------------------
1 | import type { AllHTMLAttributes, ReactNode } from 'react'
2 |
3 | import { Colors } from './Card.constants'
4 |
5 | export interface CardProps extends AllHTMLAttributes {
6 | /** The content of the card. */
7 | children?: ReactNode
8 | /** The background color of the card. */
9 | color?: `${Colors}`
10 | /** Indicates if we can dismiss the card. */
11 | dismissable?: boolean
12 | /**
13 | * The label of the small "x" dimiss button in the top right corner of the
14 | * card (if it is dismissable).
15 | */
16 | dismissButtonLabel?: string
17 | /**
18 | * Indicate the font size of the title and the body of the card.
19 | * 1 is `body-1` and 2 is `body-2`.
20 | */
21 | fontSize?: 1 | 2
22 | /**
23 | * An icon to display at the top of the card (to the left of the title if
24 | * there is one).
25 | */
26 | icon?: ReactNode
27 | /** A title to display at the top of the card. */
28 | title?: string
29 | /** Event handler called when the card is dismissed. */
30 | onDismiss?: () => void
31 | }
32 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Card/index.ts:
--------------------------------------------------------------------------------
1 | export {
2 | Colors as CardColors,
3 | DEFAULT_COLOR as DEFAULT_CARD_COLOR,
4 | } from './Card.constants.js'
5 | export { default as Card } from './Card.js'
6 | export type { CardProps } from './Card.types.js'
7 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Confirm/Confirm.constants.ts:
--------------------------------------------------------------------------------
1 | export const GROUP_NAME = 'confirm'
2 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Confirm/Confirm.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ArgTypes,
3 | Controls,
4 | Description,
5 | Meta,
6 | Primary,
7 | Stories,
8 | Subtitle,
9 | Title,
10 | } from '@storybook/blocks'
11 |
12 | import * as ConfirmStories from './Confirm.stories'
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | ---
23 |
24 | ## Props
25 |
26 | On top of all the props, attributes and event handler you can set on a
27 | `` component (and this a `` element), the component accepts the
28 | following props:
29 |
30 |
31 |
32 |
33 |
34 | ## Playground
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Confirm/Confirm.types.ts:
--------------------------------------------------------------------------------
1 | import { ButtonProps } from '@/components/Button/Button.types'
2 | import { DialogProps } from '@/components/Dialog/Dialog.types'
3 |
4 | export interface ConfirmProps
5 | extends Omit {
6 | /**
7 | * The configuration of the cancel button.
8 | *
9 | * You must provide at least a `label` or a `children` prop.
10 | */
11 | cancel:
12 | | string
13 | | Omit<
14 | ButtonProps,
15 | 'fullWidth' | 'href' | 'onClick' | 'target' | 'type' | 'variant'
16 | >
17 | /**
18 | * The configuration of the confirmation button.
19 | *
20 | * You must provide at least a `label` or a `children` prop.
21 | */
22 | confirm:
23 | | string
24 | | Omit<
25 | ButtonProps,
26 | 'fullWidth' | 'href' | 'onClick' | 'target' | 'type' | 'variant'
27 | >
28 | /**
29 | * The event handler called when the confirm dialog is dismissed or the
30 | * "Cancel" button is pressed.
31 | */
32 | onCancel?: () => void
33 | /** The event handler called when the "Confirm" button is pressed. */
34 | onConfirm?: () => void
35 | }
36 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Confirm/index.ts:
--------------------------------------------------------------------------------
1 | export { Positions as ConfirmPositions } from '../Dialog/Dialog.constants.js'
2 | export { default as Confirm } from './Confirm.js'
3 | export type { ConfirmProps } from './Confirm.types.js'
4 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/CuteIcon/CuteIcon.constants.ts:
--------------------------------------------------------------------------------
1 | export const GROUP_NAME = 'cute-icon'
2 |
3 | export enum Colors {
4 | Blue = 'blue',
5 | Green = 'green',
6 | Pink = 'pink',
7 | Purple = 'purple',
8 | Yellow = 'yellow',
9 | }
10 |
11 | export const DEFAULT_COLOR = Colors.Pink
12 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/CuteIcon/CuteIcon.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ArgTypes,
3 | Controls,
4 | Description,
5 | Meta,
6 | Primary,
7 | Stories,
8 | Subtitle,
9 | Title,
10 | } from '@storybook/blocks'
11 |
12 | import * as CuteIconStories from './CuteIcon.stories'
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | ---
23 |
24 | ## Props
25 |
26 | On top of all the props, attributes and event handler you can set on a
27 | `` element, the component accepts the following props:
28 |
29 |
30 |
31 |
32 |
33 | ## Playground
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/CuteIcon/CuteIcon.tsx:
--------------------------------------------------------------------------------
1 | import omit from 'lodash/fp/omit'
2 |
3 | import { LIGHT_BG_COLORS_CLASSNAMES, PREFIX } from '@/constants'
4 | import { cn } from '@/styles/helpers'
5 |
6 | import type { CuteIconProps } from './CuteIcon.types'
7 |
8 | import { DEFAULT_COLOR, GROUP_NAME } from './CuteIcon.constants'
9 |
10 | /**
11 | * `CuteIcon` component displays an icon in a small cute colored bubble.
12 | */
13 | export const CuteIcon = ({
14 | color = DEFAULT_COLOR,
15 | icon,
16 | ...props
17 | }: CuteIconProps) => (
18 |
28 | {icon}
29 |
30 | )
31 | CuteIcon.displayName = 'CuteIcon'
32 |
33 | export default CuteIcon
34 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/CuteIcon/CuteIcon.types.ts:
--------------------------------------------------------------------------------
1 | import type { AllHTMLAttributes, ReactNode } from 'react'
2 |
3 | import { Colors } from './CuteIcon.constants'
4 |
5 | export interface CuteIconProps extends AllHTMLAttributes {
6 | /** The icon to display. */
7 | icon: ReactNode
8 | /** The color of the bubble. */
9 | color?: `${Colors}`
10 | }
11 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/CuteIcon/index.ts:
--------------------------------------------------------------------------------
1 | export {
2 | Colors as CuteIconColors,
3 | DEFAULT_COLOR as DEFAULT_CUTE_ICON_COLOR,
4 | } from './CuteIcon.constants.js'
5 | export { default as CuteIcon } from './CuteIcon.js'
6 | export type { CuteIconProps } from './CuteIcon.types.js'
7 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/DateTimePicker/DateTimePicker.constants.ts:
--------------------------------------------------------------------------------
1 | export const GROUP_NAME = 'datetime-picker'
2 |
3 | export enum PickerVariants {
4 | SideBySide = 'side-by-side',
5 | Tabs = 'tabs',
6 | }
7 |
8 | export const DEFAULT_PICKER_VARIANT = PickerVariants.Tabs
9 |
10 | export enum TimeVariants {
11 | Clock = 'clock',
12 | }
13 |
14 | export const DEFAULT_TIME_VARIANT = TimeVariants.Clock
15 |
16 | export enum Orientations {
17 | Horizontal = 'horizontal',
18 | Responsive = 'responsive',
19 | Vertical = 'vertical',
20 | }
21 |
22 | export const DEFAULT_ORIENTATION = Orientations.Responsive
23 | export const DEFAULT_DESKTOP_ORIENTATION = Orientations.Horizontal
24 | export const DEFAULT_MOBILE_ORIENTATION = Orientations.Vertical
25 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/DateTimePicker/DateTimePicker.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ArgTypes,
3 | Controls,
4 | Description,
5 | Meta,
6 | Primary,
7 | Subtitle,
8 | Title,
9 | } from '@storybook/blocks'
10 |
11 | import * as DateTimePickerStories from './DateTimePicker.stories'
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | ---
22 |
23 | ## Props
24 |
25 | On top of all the props, attributes and event handler you can set on a ``
26 | element, the component accepts the following props:
27 |
28 |
29 |
30 | ## Playground
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/DateTimePicker/index.ts:
--------------------------------------------------------------------------------
1 | export {
2 | Orientations as DateTimeOrientations,
3 | PickerVariants as DateTimePickerVariants,
4 | TimeVariants as DateTimeTimeVariants,
5 | DEFAULT_DESKTOP_ORIENTATION as DEFAULT_DATETIME_DESKTOP_ORIENTATION,
6 | DEFAULT_MOBILE_ORIENTATION as DEFAULT_DATETIME_MOBILE_ORIENTATION,
7 | DEFAULT_ORIENTATION as DEFAULT_DATETIME_ORIENTATION,
8 | DEFAULT_PICKER_VARIANT as DEFAULT_DATETIME_PICKER_VARIANT,
9 | DEFAULT_TIME_VARIANT as DEFAULT_DATETIME_TIME_VARIANT,
10 | } from './DateTimePicker.constants.js'
11 | export { default as DateTimePicker } from './DateTimePicker.js'
12 | export type {
13 | DateTimePickerProps,
14 | CombinedRefs as DateTimePickerRefs,
15 | } from './DateTimePicker.types.js'
16 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Dialog/Dialog.constants.ts:
--------------------------------------------------------------------------------
1 | export const GROUP_NAME = 'dialog'
2 |
3 | export enum Positions {
4 | Absolute = 'absolute',
5 | Fixed = 'fixed',
6 | }
7 |
8 | export const DEFAULT_POSITION = Positions.Fixed
9 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Dialog/Dialog.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ArgTypes,
3 | Controls,
4 | Description,
5 | Meta,
6 | Primary,
7 | Stories,
8 | Subtitle,
9 | Title,
10 | } from '@storybook/blocks'
11 |
12 | import * as DialogStories from './Dialog.stories'
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | ---
23 |
24 | ## Props
25 |
26 | On top of all the props, attributes and event handler you can set on a
27 | `` element, the component accepts the following props:
28 |
29 |
30 |
31 |
32 |
33 | ## Playground
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Dialog/index.ts:
--------------------------------------------------------------------------------
1 | export {
2 | DEFAULT_POSITION as DEFAULT_DIALOG_POSITION,
3 | Positions as DialogPositions,
4 | } from './Dialog.constants.js'
5 | export { default as Dialog } from './Dialog.js'
6 | export type { DialogProps } from './Dialog.types.js'
7 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Dropdown/Dropdown.constants.ts:
--------------------------------------------------------------------------------
1 | import { PaperElevations } from '@/components/Paper'
2 |
3 | export const GROUP_NAME = 'dropdown'
4 |
5 | export const DEFAULT_ELEVATION = PaperElevations.Bordered
6 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Dropdown/Dropdown.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ArgTypes,
3 | Controls,
4 | Description,
5 | Meta,
6 | Primary,
7 | Stories,
8 | Subtitle,
9 | Title,
10 | } from '@storybook/blocks'
11 |
12 | import * as DropdownStories from './Dropdown.stories'
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | ---
23 |
24 | ## Props
25 |
26 | On top of all the props, attributes and event handler you can set on a
27 | `` element, the component accepts the following props:
28 |
29 |
30 |
31 |
32 |
33 | ## Playground
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Dropdown/DropdownContext.ts:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { createContext } from 'react'
4 |
5 | export const DropdownContext = createContext<{
6 | condensed: boolean
7 | disabled: boolean
8 | }>({ condensed: false, disabled: false })
9 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Dropdown/DropdownGroupContext.ts:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { createContext } from 'react'
4 |
5 | export const DropdownGroupContext = createContext<{
6 | condensed: boolean
7 | disabled: boolean
8 | }>({ condensed: false, disabled: false })
9 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Dropdown/DropdownItem.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ArgTypes,
3 | Controls,
4 | Description,
5 | Meta,
6 | Primary,
7 | Subtitle,
8 | Title,
9 | } from '@storybook/blocks'
10 |
11 | import * as DropdownItemStories from './DropdownItem.stories'
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | ---
22 |
23 | ## Props
24 |
25 | On top of all the props, attributes and event handler you can set on a
26 | `` element, the component accepts the following props:
27 |
28 |
29 |
30 | ## Playground
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Dropdown/DropdownItemGroup.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ArgTypes,
3 | Controls,
4 | Description,
5 | Meta,
6 | Primary,
7 | Subtitle,
8 | Title,
9 | } from '@storybook/blocks'
10 |
11 | import * as DropdownItemGroupStories from './DropdownItemGroup.stories'
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | ---
22 |
23 | ## Props
24 |
25 | On top of all the props, attributes and event handler you can set on a
26 | `` element, the component accepts the following props:
27 |
28 |
29 |
30 | ## Playground
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Dropdown/DropdownItemGroup.stories.tsx:
--------------------------------------------------------------------------------
1 | import type { Meta, StoryObj } from '@storybook/react'
2 |
3 | import type { ComponentProps } from 'react'
4 |
5 | import { Dropdown, DropdownItem, DropdownItemGroup } from '.'
6 |
7 | type DropdownItemGroupProps = ComponentProps
8 |
9 | const meta: Meta = {
10 | args: {
11 | condensed: false,
12 | disabled: false,
13 | label: 'Jedis',
14 | },
15 | argTypes: {
16 | children: {
17 | control: false,
18 | table: {
19 | type: {
20 | summary:
21 | 'DropdownItem | DropdownItemSeparator | SubDropdown | DropdownRadioGroup | Array',
22 | },
23 | },
24 | },
25 | },
26 | component: DropdownItemGroup,
27 | parameters: {
28 | chromatic: { delay: 2000 },
29 | },
30 |
31 | title: 'Molecules/Dropdown/DropdownItemGroup',
32 | } satisfies Meta
33 |
34 | export default meta
35 | type Story = StoryObj
36 |
37 | export const Playground: Story = {
38 | render: ({ condensed = false, disabled = false, label }) => (
39 |
40 |
41 |
46 |
47 |
48 |
49 |
50 |
51 |
52 | ),
53 | }
54 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Dropdown/DropdownItemSeparator.mdx:
--------------------------------------------------------------------------------
1 | import { Description, Meta, Primary, Subtitle, Title } from '@storybook/blocks'
2 |
3 | import * as DropdownItemSeparatortories from './DropdownItemSeparator.stories'
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | ---
14 |
15 | ## Props
16 |
17 | You can pass any props, attributes and event handler you can set on a
18 | `` element.
19 |
20 | ## Playground
21 |
22 |
23 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Dropdown/DropdownItemSeparator.stories.tsx:
--------------------------------------------------------------------------------
1 | import type { Meta, StoryObj } from '@storybook/react'
2 |
3 | import type { ComponentProps } from 'react'
4 |
5 | import { Typography } from '@/components/Typography'
6 |
7 | import { Dropdown, DropdownItem, DropdownItemSeparator } from '.'
8 |
9 | type DropdownItemSeparatorProps = ComponentProps
10 |
11 | const meta: Meta = {
12 | component: DropdownItemSeparator,
13 | parameters: {
14 | chromatic: { delay: 2000 },
15 | },
16 |
17 | title: 'Molecules/Dropdown/DropdownItemSeparator',
18 | } satisfies Meta
19 |
20 | export default meta
21 | type Story = StoryObj
22 |
23 | export const Playground: Story = {
24 | render: () => (
25 |
26 |
27 | Normal dropdown
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 | Condensed dropdown
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 | ),
47 | }
48 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Dropdown/DropdownItemSeparator.tsx:
--------------------------------------------------------------------------------
1 | import * as RxSelect from '@radix-ui/react-select'
2 |
3 | import omit from 'lodash/fp/omit'
4 |
5 | import { PREFIX } from '@/constants'
6 | import { cn } from '@/styles/helpers'
7 |
8 | import { GROUP_NAME } from './Dropdown.constants'
9 | import { DropdownItemSeparatorProps } from './Dropdown.types'
10 |
11 | /**
12 | * `ItemSeparator` component is used to display a separator between groups or
13 | * items in a dropdown.
14 | *
15 | * See https://www.radix-ui.com/primitives/docs/components/select#separator for
16 | * more information.
17 | */
18 | export default function DropdownItemSeparator({
19 | ...props
20 | }: DropdownItemSeparatorProps) {
21 | return (
22 |
30 | )
31 | }
32 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Dropdown/DropdownRadioGroup.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ArgTypes,
3 | Controls,
4 | Description,
5 | Meta,
6 | Primary,
7 | Stories,
8 | Subtitle,
9 | Title,
10 | } from '@storybook/blocks'
11 |
12 | import * as DropdownRadioGroupStories from './DropdownRadioGroup.stories'
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | ---
23 |
24 | ## Props
25 |
26 | On top of all the props, attributes and event handler you can set on a
27 | `` component (and thus a `` element), the component
28 | accepts the following props:
29 |
30 |
31 |
32 |
33 |
34 | ## Playground
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Dropdown/DropdownRadioItem.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ArgTypes,
3 | Controls,
4 | Description,
5 | Meta,
6 | Primary,
7 | Subtitle,
8 | Title,
9 | } from '@storybook/blocks'
10 |
11 | import * as DropdownRadioItemStories from './DropdownRadioItem.stories'
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | ---
22 |
23 | ## Props
24 |
25 | On top of all the props, attributes and event handler you can set on a
26 | `` component (and thus a `` element), the component
27 | accepts the following props:
28 |
29 |
30 |
31 | ## Playground
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Dropdown/DropdownRadioItem.stories.tsx:
--------------------------------------------------------------------------------
1 | import type { Meta, StoryObj } from '@storybook/react'
2 |
3 | import { action } from '@storybook/addon-actions'
4 |
5 | import type { ComponentProps } from 'react'
6 |
7 | import { Dropdown, DropdownRadioGroup, DropdownRadioItem } from '.'
8 |
9 | type DropdownRadioItemProps = ComponentProps
10 |
11 | const meta: Meta = {
12 | args: {
13 | condensed: false,
14 | disabled: false,
15 | label: 'Jar Jar Binks',
16 | value: 'jar-jar-binks',
17 | },
18 | argTypes: {
19 | asChild: { table: { disable: true } },
20 | },
21 | component: DropdownRadioItem,
22 |
23 | title: 'Molecules/Dropdown/DropdownRadio/DropdownRadioItem',
24 | } satisfies Meta
25 |
26 | export default meta
27 | type Story = StoryObj
28 |
29 | export const Playground: Story = {
30 | render: ({ condensed = false, disabled = false, label, value }) => (
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 | ),
39 | }
40 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Dropdown/SubDropdown.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ArgTypes,
3 | Controls,
4 | Description,
5 | Meta,
6 | Primary,
7 | Subtitle,
8 | Title,
9 | } from '@storybook/blocks'
10 |
11 | import * as SubDropdownStories from './SubDropdown.stories'
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | ---
22 |
23 | ## Props
24 |
25 | On top of all the props, attributes and event handler you can set on a
26 | `` element, the component accepts the following props:
27 |
28 |
29 |
30 | ## Playground
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Dropdown/index.ts:
--------------------------------------------------------------------------------
1 | export { Elevations as DropdownElevations } from '../Paper/Paper.constants.js'
2 | export { DEFAULT_ELEVATION as DEFAULT_DROPDOWN_ELEVATION } from './Dropdown.constants.js'
3 | export { default as Dropdown } from './Dropdown.js'
4 | export type {
5 | DropdownItemGroupProps,
6 | DropdownItemProps,
7 | DropdownItemSeparatorProps,
8 | DropdownProps,
9 | DropdownRadioGroupProps,
10 | DropdownRadioItemProps,
11 | } from './Dropdown.types.js'
12 | export { default as DropdownItem } from './DropdownItem.js'
13 | export { default as DropdownItemGroup } from './DropdownItemGroup.js'
14 | export { default as DropdownItemSeparator } from './DropdownItemSeparator.js'
15 | export { default as DropdownRadioGroup } from './DropdownRadioGroup.js'
16 | export { default as DropdownRadioItem } from './DropdownRadioItem.js'
17 | export { default as SubDropdown } from './SubDropdown.js'
18 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/EmojiPicker/Emoji.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ArgTypes,
3 | Controls,
4 | Description,
5 | Meta,
6 | Primary,
7 | Subtitle,
8 | Title,
9 | } from '@storybook/blocks'
10 |
11 | import * as EmojiStories from './Emoji.stories'
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | ---
22 |
23 | > **Its is important to note that to be able to use this component, you must
24 | > have loaded the `emoji-mart` data first:**
25 | >
26 | > ```js
27 | > import data from '@emoji-mart/data'
28 | > import { init } from 'emoji-mart'
29 | >
30 | > init({ data })
31 | > ```
32 | >
33 | > **See https://github.com/missive/emoji-mart#-emoji-component for more
34 | > information**.
35 |
36 | ---
37 |
38 | ## Props
39 |
40 | On top of all the props, attributes and event handler you can set on a
41 | `` element, the component accepts the following props:
42 |
43 |
44 |
45 | ## Playground
46 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/EmojiPicker/Emoji.stories.tsx:
--------------------------------------------------------------------------------
1 | import type { Meta, StoryObj } from '@storybook/react'
2 |
3 | import data from '@emoji-mart/data'
4 | import { init } from 'emoji-mart'
5 |
6 | import type { ComponentProps } from 'react'
7 |
8 | import { Typography } from '@/components/Typography'
9 |
10 | import { Emoji } from '.'
11 | import {
12 | DEFAULT_EMOJIS_SET,
13 | DEFAULT_SKIN_TONE,
14 | EmojisSets,
15 | SKIN_TONES,
16 | } from './EmojiPicker.constants'
17 |
18 | init({ data })
19 |
20 | type EmojiProps = ComponentProps
21 |
22 | const meta = {
23 | args: {
24 | id: '+1',
25 | native: '',
26 | set: DEFAULT_EMOJIS_SET,
27 | shortCode: '',
28 | skinTone: DEFAULT_SKIN_TONE,
29 | },
30 | argTypes: {
31 | set: {
32 | options: Object.values(EmojisSets),
33 | table: {
34 | defaultValue: { summary: DEFAULT_EMOJIS_SET },
35 | type: { summary: Object.values(EmojisSets).join('|') },
36 | },
37 | },
38 | skinTone: {
39 | options: SKIN_TONES as unknown as Array,
40 | table: {
41 | defaultValue: { summary: `${DEFAULT_SKIN_TONE}` },
42 | type: { summary: SKIN_TONES.join('|') },
43 | },
44 | },
45 | },
46 | component: Emoji,
47 | parameters: {
48 | docs: { subtitle: '💃 Everybody, do the Emoji Pop! - The Emoji Movie' },
49 | },
50 |
51 | title: 'Molecules/Emojis/Emoji',
52 | } satisfies Meta
53 |
54 | export default meta
55 | type Story = StoryObj
56 |
57 | export const Playground: Story = {
58 | render: (arguments_) => (
59 |
60 |
61 |
62 | ),
63 | }
64 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/EmojiPicker/EmojiPicker.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ArgTypes,
3 | Controls,
4 | Description,
5 | Meta,
6 | Primary,
7 | Subtitle,
8 | Title,
9 | } from '@storybook/blocks'
10 |
11 | import * as EmojiPickerStories from './EmojiPicker.stories'
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | ---
22 |
23 | ## Props
24 |
25 | On top of all the props, attributes and event handler you can set on a
26 | `` element, the component accepts the following props:
27 |
28 |
29 |
30 | ## Playground
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/EmojiPicker/index.ts:
--------------------------------------------------------------------------------
1 | export { default as Emoji } from './Emoji.js'
2 | export {
3 | DEFAULT_CATEGORIES as DEFAULT_EMOJI_PICKER_CATEGORIES,
4 | DEFAULT_EMOJIS_SET as DEFAULT_EMOJI_PICKER_EMOJIS_SET,
5 | DEFAULT_VERSION as DEFAULT_EMOJI_PICKER_EMOJIS_VERSION,
6 | DEFAULT_LOCALE as DEFAULT_EMOJI_PICKER_LOCALE,
7 | DEFAULT_NAV_POSITION as DEFAULT_EMOJI_PICKER_NAV_POSITION,
8 | DEFAULT_PREVIEW_POSITION as DEFAULT_EMOJI_PICKER_PREVIEW_POSITION,
9 | DEFAULT_SEARCH_POSITION as DEFAULT_EMOJI_PICKER_SEARCH_POSITION,
10 | DEFAULT_SKIN_TONE as DEFAULT_EMOJI_PICKER_SKIN_TONE,
11 | DEFAULT_SKIN_TONE_POSITION as DEFAULT_EMOJI_PICKER_SKIN_TONE_POSITION,
12 | DEFAULT_SKIN_TONE as DEFAULT_EMOJI_SKIN_TONE,
13 | Categories as EmojiPickerCategories,
14 | EmojisSets as EmojiPickerEmojisSets,
15 | VERSIONS as EmojiPickerEmojisVersions,
16 | Locales as EmojiPickerLocales,
17 | Positions as EmojiPickerNavPositions,
18 | Positions as EmojiPickerPreviewPositions,
19 | SearchPositions as EmojiPickerSearchPositions,
20 | SkinTonePositions as EmojiPickerSkinTonePositions,
21 | SKIN_TONES as EmojiPickerSkinTones,
22 | SKIN_TONES as EmojiSkinTones,
23 | EmojisSets,
24 | SKIN_TONES as SkinTones,
25 | } from './EmojiPicker.constants.js'
26 | export { default as EmojiPicker } from './EmojiPicker.js'
27 | export type {
28 | EmojiPickerProps,
29 | EmojiProps,
30 | EmojisCategory,
31 | Emoji as EmojiType,
32 | } from './EmojiPicker.types.js'
33 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Header/Header.constants.ts:
--------------------------------------------------------------------------------
1 | export const GROUP_NAME = 'header'
2 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Header/Header.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ArgTypes,
3 | Controls,
4 | Description,
5 | Meta,
6 | Primary,
7 | Subtitle,
8 | Title,
9 | } from '@storybook/blocks'
10 |
11 | import * as HeaderStories from './Header.stories'
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | ---
22 |
23 | ## Props
24 |
25 | On top of all the props, attributes and event handler you can set on a
26 | `` element, the component accepts the following props:
27 |
28 |
29 |
30 | ## Playground
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Header/Header.types.ts:
--------------------------------------------------------------------------------
1 | import type { AllHTMLAttributes, MouseEvent, ReactNode } from 'react'
2 |
3 | export interface HeaderProps extends AllHTMLAttributes {
4 | /** The content to display in the middle of the header. */
5 | children?: ReactNode
6 | /** The content to display on the left of the header. */
7 | left?: ReactNode
8 | /** The content to display on the right of the header. */
9 | right?: ReactNode
10 | /** The event handler called when the header is clicked. */
11 | onClick?: (event: MouseEvent) => void
12 | }
13 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Header/index.ts:
--------------------------------------------------------------------------------
1 | export { default as Header } from './Header.js'
2 | export type { HeaderProps } from './Header.types.js'
3 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/InputCheckbox/InputCheckbox.constants.ts:
--------------------------------------------------------------------------------
1 | export const GROUP_NAME = 'input-checkbox'
2 |
3 | export enum Variants {
4 | Primary = 'primary',
5 | Secondary = 'secondary',
6 | Tertiary = 'tertiary',
7 | }
8 |
9 | export const DEFAULT_VARIANT = Variants.Primary
10 |
11 | export enum Colors {
12 | Blue = 'blue',
13 | Green = 'green',
14 | Pink = 'pink',
15 | Purple = 'purple',
16 | Yellow = 'yellow',
17 | }
18 |
19 | export const DEFAULT_COLOR = Colors.Pink
20 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/InputCheckbox/InputCheckbox.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ArgTypes,
3 | Controls,
4 | Description,
5 | Meta,
6 | Primary,
7 | Stories,
8 | Subtitle,
9 | Title,
10 | } from '@storybook/blocks'
11 |
12 | import * as InputCheckboxStories from './InputCheckbox.stories'
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | ---
23 |
24 | ## Props
25 |
26 | On top of all the props, attributes and event handler you can set on a
27 | `` element, the component accepts the following props:
28 |
29 |
30 |
31 |
32 |
33 | ## Playground
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/InputCheckbox/index.ts:
--------------------------------------------------------------------------------
1 | export {
2 | DEFAULT_COLOR as DEFAULT_INPUT_CHECKBOX_COLOR,
3 | DEFAULT_VARIANT as DEFAULT_INPUT_CHECKBOX_VARIANT,
4 | Variants as InputCheckboxVariants,
5 | } from './InputCheckbox.constants.js'
6 | export { default as InputCheckbox } from './InputCheckbox.js'
7 | export type { InputCheckboxProps } from './InputCheckbox.types.js'
8 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/InputDate/InputDate.constants.ts:
--------------------------------------------------------------------------------
1 | export const GROUP_NAME = 'input-date'
2 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/InputDate/InputDate.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ArgTypes,
3 | Controls,
4 | Description,
5 | Meta,
6 | Primary,
7 | Subtitle,
8 | Title,
9 | } from '@storybook/blocks'
10 |
11 | import * as InputDateStories from './InputDate.stories'
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | ---
22 |
23 | ## Props
24 |
25 | On top of all the props, attributes and event handler you can set on a
26 | `` component (and thus a `` element), the component
27 | accepts the following props:
28 |
29 |
30 |
31 | ## Playground
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/InputDate/index.ts:
--------------------------------------------------------------------------------
1 | export { default as InputDate } from './InputDate.js'
2 | export type {
3 | DateFormat,
4 | Descriptions,
5 | InputDateProps,
6 | CombinedRefs as InputDateRefs,
7 | Placeholders,
8 | } from './InputDate.types.js'
9 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/InputFile/InputFile.constants.ts:
--------------------------------------------------------------------------------
1 | export const GROUP_NAME = 'inputFile'
2 |
3 | export enum Variants {
4 | Display = 'display',
5 | Primary = 'primary',
6 | Secondary = 'secondary',
7 | Text = 'text',
8 | }
9 |
10 | export const DEFAULT_VARIANT = Variants.Primary
11 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/InputFile/InputFile.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ArgTypes,
3 | Controls,
4 | Description,
5 | Meta,
6 | Primary,
7 | Stories,
8 | Subtitle,
9 | Title,
10 | } from '@storybook/blocks'
11 |
12 | import * as InputFileStories from './InputFile.stories'
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | ---
23 |
24 | ## Props
25 |
26 | On top of all the props, attributes and event handler you can set on a
27 | `` element, the component accepts the following props:
28 |
29 |
30 |
31 |
32 |
33 | ## Playground
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/InputFile/InputFile.types.ts:
--------------------------------------------------------------------------------
1 | import type { AllHTMLAttributes } from 'react'
2 |
3 | import { ButtonProps } from '@/components/Button/Button.types'
4 |
5 | import { Variants } from './InputFile.constants'
6 |
7 | export type CombinedRefs = {
8 | fileInput: HTMLInputElement | null
9 | trigger: HTMLButtonElement | null
10 | }
11 |
12 | export interface InputFileProps
13 | extends Omit, 'onChange'> {
14 | /** The label of the trigger of the input file. */
15 | label: string
16 | /** Prevents the user from interacting with the input file and the trigger. */
17 | disabled?: boolean
18 | /** The props to pass to the trigger of the input file. */
19 | triggerProps?: Partial<
20 | Omit<
21 | ButtonProps,
22 | 'disabled' | 'href' | 'label' | 'target' | 'type' | 'variant'
23 | >
24 | >
25 | /**
26 | * The variant of the input file.
27 | *
28 | * Currently, only trigger button variants are available (and the variants
29 | * name follow the variants name of the `Button` component).
30 | */
31 | variant?: `${Variants}`
32 | /** Event handler called when one or multiple files are selected. */
33 | onChange?: (files: FileList | null) => void
34 | }
35 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/InputFile/index.ts:
--------------------------------------------------------------------------------
1 | export {
2 | DEFAULT_VARIANT as DEFAULT_INPUT_FILE_VARIANT,
3 | Variants as InputFileVariants,
4 | } from './InputFile.constants.js'
5 | export { default as InputFile } from './InputFile.js'
6 | export type { InputFileProps } from './InputFile.types.js'
7 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/InputPhone/InputPhone.constants.ts:
--------------------------------------------------------------------------------
1 | import getUnicodeFlagIcon from 'country-flag-icons/unicode'
2 | import { getCountries, getCountryCallingCode } from 'libphonenumber-js/max'
3 |
4 | import { CountryDetails } from './InputPhone.types'
5 |
6 | export const GROUP_NAME = 'input-phone'
7 |
8 | export const DEFAULT_COUNTRY_CODE = 'FR'
9 |
10 | export const countryByCountryCode: Record = {}
11 | export const supportedCountries = getCountries().map((countryCode) => {
12 | const countryDetails: CountryDetails = {
13 | countryCode,
14 | countryName:
15 | new Intl.DisplayNames(undefined, { type: 'region' }).of(countryCode) ||
16 | 'Unknown',
17 | flag: getUnicodeFlagIcon(countryCode),
18 | prefix: getCountryCallingCode(countryCode),
19 | }
20 |
21 | countryByCountryCode[countryDetails.countryCode] = countryDetails
22 |
23 | return countryDetails
24 | })
25 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/InputPhone/InputPhone.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ArgTypes,
3 | Controls,
4 | Description,
5 | Meta,
6 | Primary,
7 | Subtitle,
8 | Title,
9 | } from '@storybook/blocks'
10 |
11 | import * as InputPhoneStories from './InputPhone.stories'
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | ---
22 |
23 | ## Props
24 |
25 | On top of all the props, attributes and event handler you can set on a
26 | `` component (and thus a `` element), the component
27 | accepts the following props:
28 |
29 |
30 |
31 | ## Playground
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/InputPhone/index.ts:
--------------------------------------------------------------------------------
1 | export {
2 | DEFAULT_COUNTRY_CODE as DEFAULT_INPUT_PHONE_COUNTRY_CODE,
3 | countryByCountryCode as inputPhoneCountryByCountryCode,
4 | supportedCountries as inputPhoneSupportedCountries,
5 | } from './InputPhone.constants.js'
6 | export { default as InputPhone } from './InputPhone.js'
7 | export type {
8 | InputPhoneProps,
9 | CombinedRefs as InputPhoneRefs,
10 | PhoneNumber,
11 | } from './InputPhone.types.js'
12 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/InputPinCode/InputPinCode.constants.ts:
--------------------------------------------------------------------------------
1 | export const GROUP_NAME = 'input-pincode'
2 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/InputPinCode/InputPinCode.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ArgTypes,
3 | Controls,
4 | Description,
5 | Meta,
6 | Primary,
7 | Subtitle,
8 | Title,
9 | } from '@storybook/blocks'
10 |
11 | import * as InputPinCodeStories from './InputPinCode.stories'
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | ---
22 |
23 | ## Props
24 |
25 | On top of all the props, attributes and event handler you can set on a
26 | `` component (and thus a `` element), the component
27 | accepts the following props:
28 |
29 |
30 |
31 | ## Playground
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/InputPinCode/index.ts:
--------------------------------------------------------------------------------
1 | export { default as InputPinCode } from './InputPinCode.js'
2 | export type { InputPinCodeProps } from './InputPinCode.types.js'
3 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/InputRadio/InputRadio.constants.ts:
--------------------------------------------------------------------------------
1 | export const GROUP_NAME = 'input-radio'
2 |
3 | export enum Variants {
4 | Primary = 'primary',
5 | Secondary = 'secondary',
6 | Tertiary = 'tertiary',
7 | }
8 |
9 | export const DEFAULT_VARIANT = Variants.Primary
10 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/InputRadio/InputRadio.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ArgTypes,
3 | Controls,
4 | Description,
5 | Meta,
6 | Primary,
7 | Subtitle,
8 | Title,
9 | } from '@storybook/blocks'
10 |
11 | import * as InputRadioStories from './InputRadio.stories'
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | ---
22 |
23 | ## Props
24 |
25 | On top of all the props, attributes and event handler you can set on a
26 | `` element, the component accepts the following props:
27 |
28 |
29 |
30 | ## Playground
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/InputRadio/InputRadio.stories.tsx:
--------------------------------------------------------------------------------
1 | import type { Meta, StoryObj } from '@storybook/react'
2 |
3 | import { action } from '@storybook/addon-actions'
4 |
5 | import type { ComponentProps } from 'react'
6 |
7 | import { InputRadio, InputRadioGroup } from '.'
8 |
9 | type InputRadioProps = ComponentProps
10 |
11 | const meta: Meta<{ required?: boolean } & InputRadioProps> = {
12 | args: {
13 | condensed: false,
14 | disabled: false,
15 | fullWidth: false,
16 | label: 'Jar Jar Binks',
17 | required: false,
18 | value: 'jar-jar-binks',
19 | },
20 | argTypes: {
21 | asChild: { table: { disable: true } },
22 | },
23 | component: InputRadio,
24 | parameters: {
25 | docs: { subtitle: '🎶 Video killed the radio star - The Buggles' },
26 | },
27 |
28 | title: 'Molecules/Input/InputRadio',
29 | } satisfies Meta<{ required?: boolean } & InputRadioProps>
30 |
31 | export default meta
32 | type Story = StoryObj
33 |
34 | export const Playground: Story = {
35 | render: ({
36 | condensed = false,
37 | disabled = false,
38 | fullWidth = false,
39 | label,
40 | required = false,
41 | value,
42 | }) => (
43 |
48 |
55 |
56 | ),
57 | }
58 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/InputRadio/InputRadioContext.ts:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { createContext } from 'react'
4 |
5 | import { DEFAULT_VARIANT, Variants } from './InputRadio.constants'
6 |
7 | export const InputRadioContext = createContext<{
8 | condensed: boolean
9 | disabled: boolean
10 | required: boolean
11 | variant: `${Variants}`
12 | }>({
13 | condensed: false,
14 | disabled: false,
15 | required: false,
16 | variant: DEFAULT_VARIANT,
17 | })
18 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/InputRadio/InputRadioGroup.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ArgTypes,
3 | Controls,
4 | Description,
5 | Meta,
6 | Primary,
7 | Stories,
8 | Subtitle,
9 | Title,
10 | } from '@storybook/blocks'
11 |
12 | import * as InputRadioGroupStories from './InputRadioGroup.stories'
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | ---
23 |
24 | ## Props
25 |
26 | On top of all the props, attributes and event handler you can set on a
27 | `` element, the component accepts the following props:
28 |
29 |
30 |
31 |
32 |
33 | ## Playground
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/InputRadio/index.ts:
--------------------------------------------------------------------------------
1 | export {
2 | DEFAULT_VARIANT as DEFAULT_INPUT_RADIO_VARIANT,
3 | Variants as InputRadioVariants,
4 | } from './InputRadio.constants.js'
5 | export { default as InputRadio } from './InputRadio.js'
6 | export type {
7 | InputRadioGroupProps,
8 | InputRadioProps,
9 | } from './InputRadio.types.js'
10 | export { default as InputRadioGroup } from './InputRadioGroup.js'
11 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/InputText/InputText.constants.ts:
--------------------------------------------------------------------------------
1 | export const GROUP_NAME = 'input-text'
2 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/InputText/InputText.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ArgTypes,
3 | Controls,
4 | Description,
5 | Meta,
6 | Primary,
7 | Stories,
8 | Subtitle,
9 | Title,
10 | } from '@storybook/blocks'
11 |
12 | import * as InputTextStories from './InputText.stories'
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | ---
23 |
24 | ## Props
25 |
26 | On top of all the props, attributes and event handler you can set on a
27 | `` element, the component accepts the following props:
28 |
29 |
30 |
31 |
32 |
33 | ## Playground
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/InputText/index.ts:
--------------------------------------------------------------------------------
1 | export { default as InputText } from './InputText.js'
2 | export type { InputTextProps } from './InputText.types.js'
3 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Loader/Loader.constants.ts:
--------------------------------------------------------------------------------
1 | export const GROUP_NAME = 'loader'
2 |
3 | export enum Sizes {
4 | // Extra Extra Small.
5 | XXS = 'xxs',
6 |
7 | // Extra Small.
8 | XS = 'xs',
9 |
10 | // Small.
11 | S = 's',
12 |
13 | // Medium.
14 | M = 'm',
15 |
16 | // Large.
17 | L = 'l',
18 |
19 | // Extra Large.
20 | XL = 'xl',
21 | }
22 |
23 | export const DEFAULT_SIZE = Sizes.M
24 |
25 | export const DURATION = '3.5s'
26 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Loader/Loader.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ArgTypes,
3 | Controls,
4 | Description,
5 | Meta,
6 | Primary,
7 | Stories,
8 | Subtitle,
9 | Title,
10 | } from '@storybook/blocks'
11 |
12 | import * as LoaderStories from './Loader.stories'
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | ---
23 |
24 | ## Props
25 |
26 | On top of all the props, attributes and event handler you can set on a
27 | `` element, the component accepts the following props:
28 |
29 |
30 |
31 |
32 |
33 | ## Playground
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Loader/Loader.stories.tsx:
--------------------------------------------------------------------------------
1 | import type { Meta, StoryObj } from '@storybook/react'
2 |
3 | import type { ComponentProps } from 'react'
4 |
5 | import { Loader, LoaderSizes } from '.'
6 | import { DEFAULT_SIZE } from './Loader.constants'
7 |
8 | type LoaderProps = ComponentProps
9 |
10 | const meta = {
11 | argTypes: {
12 | size: {
13 | options: Object.values(LoaderSizes),
14 | table: {
15 | defaultValue: { summary: DEFAULT_SIZE },
16 | type: { summary: Object.values(LoaderSizes).join('|') },
17 | },
18 | },
19 | },
20 | component: Loader,
21 | parameters: {
22 | docs: { subtitle: `👷♀️ Well, I can drive that loader - Ripley - Alien` },
23 | },
24 |
25 | title: 'Molecules/Loader',
26 | } satisfies Meta
27 |
28 | export default meta
29 | type Story = StoryObj
30 |
31 | export const Playground: Story = {
32 | args: {
33 | size: DEFAULT_SIZE,
34 | },
35 | }
36 |
37 | export const Loaders: Story = {
38 | render: () => (
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | ),
48 | }
49 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Loader/Loader.types.ts:
--------------------------------------------------------------------------------
1 | import type { AllHTMLAttributes } from 'react'
2 |
3 | import { Sizes } from './Loader.constants'
4 |
5 | export interface LoaderProps
6 | extends Omit, 'size'> {
7 | /**
8 | * The accessible label of the loader.
9 | *
10 | * If provided, this will be used as the `aria-label` and the `title` of the
11 | * loader.
12 | */
13 | label?: string
14 | /** The wanted size of the loader. */
15 | size?: `${Sizes}`
16 | }
17 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Loader/index.ts:
--------------------------------------------------------------------------------
1 | export {
2 | DURATION as DEFAULT_LOADER_DURATION,
3 | DEFAULT_SIZE as DEFAULT_LOADER_SIZE,
4 | Sizes as LoaderSizes,
5 | } from './Loader.constants.js'
6 | export { default as Loader } from './Loader.js'
7 | export type { LoaderProps } from './Loader.types.js'
8 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Logo/Logo.constants.ts:
--------------------------------------------------------------------------------
1 | import {
2 | ColorBrandPrimary,
3 | ColorTextDark,
4 | ColorTextLight,
5 | } from '@snowball-tech/design-tokens'
6 |
7 | export const GROUP_NAME = 'logo'
8 |
9 | export enum Sizes {
10 | // Small.
11 | S = 's',
12 |
13 | // Medium
14 | M = 'm',
15 |
16 | // Large.
17 | L = 'l',
18 |
19 | // Extra Large.
20 | XL = 'xl',
21 |
22 | // Fluid.
23 | Fluid = 'fluid',
24 | }
25 |
26 | export const DEFAULT_SIZE = Sizes.Fluid
27 |
28 | export const PictoColors = {
29 | dark: ColorTextDark,
30 | light: ColorTextLight,
31 | none: 'transparent',
32 | primary: ColorBrandPrimary,
33 | }
34 |
35 | export const DEFAULT_PICTO_COLOR = 'dark'
36 |
37 | export const BrandColors = {
38 | dark: ColorTextDark,
39 | light: ColorTextLight,
40 | none: 'transparent',
41 | primary: ColorBrandPrimary,
42 | }
43 |
44 | export const DEFAULT_BRAND_COLOR = 'dark'
45 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Logo/Logo.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ArgTypes,
3 | Controls,
4 | Description,
5 | Meta,
6 | Primary,
7 | Stories,
8 | Subtitle,
9 | Title,
10 | } from '@storybook/blocks'
11 |
12 | import * as LogoStories from './Logo.stories'
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | ---
23 |
24 | ## Props
25 |
26 | On top of all the props, attributes and event handler you can set on a
27 | `` element, the component accepts the following props:
28 |
29 |
30 |
31 |
32 |
33 | ## Playground
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Logo/Logo.types.ts:
--------------------------------------------------------------------------------
1 | import type { AllHTMLAttributes } from 'react'
2 |
3 | import { BrandColors, PictoColors, Sizes } from './Logo.constants'
4 |
5 | export interface LogoProps
6 | extends Omit, 'size'> {
7 | /** The color of the brand name text. */
8 | brandVariant?: keyof typeof BrandColors
9 | /** The color of the picto. */
10 | pictoVariant?: keyof typeof PictoColors
11 | /** The wanted size of the loader. */
12 | size?: `${Sizes}`
13 | }
14 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Logo/index.ts:
--------------------------------------------------------------------------------
1 | export {
2 | DEFAULT_BRAND_COLOR as DEFAULT_LOGO_BRAND_COLOR,
3 | DEFAULT_PICTO_COLOR as DEFAULT_LOGO_PICTO_COLOR,
4 | DEFAULT_SIZE as DEFAULT_LOGO_SIZE,
5 | BrandColors as LogoBrandColors,
6 | PictoColors as LogoPictoColors,
7 | Sizes as LogoSizes,
8 | } from './Logo.constants.js'
9 | export { default as Logo } from './Logo.js'
10 | export type { LogoProps } from './Logo.types.js'
11 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Menu/Menu.constants.ts:
--------------------------------------------------------------------------------
1 | import { Elevations } from '@/components/Paper/Paper.constants'
2 |
3 | export const GROUP_NAME = 'menu'
4 |
5 | export enum Orientations {
6 | Horizontal = 'horizontal',
7 | Vertical = 'vertical',
8 | }
9 |
10 | export const DEFAULT_ORIENTATION = Orientations.Vertical
11 |
12 | export const DEFAULT_ELEVATION = Elevations.Elevated
13 | export const DEFAULT_SUB_MENU_ELEVATION = Elevations.Bordered
14 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Menu/Menu.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ArgTypes,
3 | Controls,
4 | Description,
5 | Meta,
6 | Primary,
7 | Stories,
8 | Subtitle,
9 | Title,
10 | } from '@storybook/blocks'
11 |
12 | import * as MenuStories from './Menu.stories'
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | ---
23 |
24 | ## Props
25 |
26 | On top of all the props, attributes and event handler you can set on a
27 | `` element, the component accepts the following props:
28 |
29 |
30 |
31 |
32 |
33 | ## Playground
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Menu/MenuContext.ts:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { createContext } from 'react'
4 |
5 | import { DEFAULT_ORIENTATION, Orientations } from './Menu.constants'
6 |
7 | export const MenuContext = createContext<{
8 | condensed: boolean
9 | disabled: boolean
10 | orientation: `${Orientations}`
11 | }>({ condensed: false, disabled: false, orientation: DEFAULT_ORIENTATION })
12 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Menu/MenuGroupContext.ts:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { createContext } from 'react'
4 |
5 | export const MenuGroupContext = createContext<{
6 | condensed: boolean
7 | disabled: boolean
8 | }>({ condensed: false, disabled: false })
9 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Menu/MenuItem.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ArgTypes,
3 | Controls,
4 | Description,
5 | Meta,
6 | Primary,
7 | Subtitle,
8 | Title,
9 | } from '@storybook/blocks'
10 |
11 | import * as MenuItemStories from './MenuItem.stories'
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | ---
22 |
23 | ## Props
24 |
25 | On top of all the props, attributes and event handler you can set on a
26 | `` element, the component accepts the following props:
27 |
28 |
29 |
30 | ## Playground
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Menu/MenuItemGroup.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ArgTypes,
3 | Controls,
4 | Description,
5 | Meta,
6 | Primary,
7 | Subtitle,
8 | Title,
9 | } from '@storybook/blocks'
10 |
11 | import * as MenuItemGroupStories from './MenuItemGroup.stories'
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | ---
22 |
23 | ## Props
24 |
25 | On top of all the props, attributes and event handler you can set on a
26 | `` element, the component accepts the following props:
27 |
28 |
29 |
30 | ## Playground
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Menu/MenuItemSeparator.mdx:
--------------------------------------------------------------------------------
1 | import { Description, Meta, Primary, Subtitle, Title } from '@storybook/blocks'
2 |
3 | import * as MenuItemSeparatortories from './MenuItemSeparator.stories'
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | ---
14 |
15 | ## Props
16 |
17 | You can pass any props, attributes and event handler you can set on a
18 | `` element.
19 |
20 | ## Playground
21 |
22 |
23 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Menu/MenuItemSeparator.stories.tsx:
--------------------------------------------------------------------------------
1 | import type { Meta, StoryObj } from '@storybook/react'
2 |
3 | import type { ComponentProps } from 'react'
4 |
5 | import { Typography } from '@/components/Typography'
6 |
7 | import { Menu, MenuItem, MenuItemSeparator } from '.'
8 |
9 | type MenuItemSeparatorProps = ComponentProps
10 |
11 | const meta: Meta = {
12 | component: MenuItemSeparator,
13 | parameters: {
14 | chromatic: { delay: 2000 },
15 | },
16 |
17 | title: 'Molecules/Menu/MenuItemSeparator',
18 | } satisfies Meta
19 |
20 | export default meta
21 | type Story = StoryObj
22 |
23 | export const Playground: Story = {
24 | render: () => (
25 |
26 |
27 | Normal menu
28 |
29 |
34 |
35 |
36 |
37 | Condensed menu
38 |
39 |
44 |
45 |
46 | ),
47 | }
48 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Menu/MenuItemSeparator.tsx:
--------------------------------------------------------------------------------
1 | import * as RxSelect from '@radix-ui/react-select'
2 |
3 | import omit from 'lodash/fp/omit'
4 |
5 | import { PREFIX } from '@/constants'
6 | import { cn } from '@/styles/helpers'
7 |
8 | import { GROUP_NAME } from './Menu.constants'
9 | import { MenuItemSeparatorProps } from './Menu.types'
10 |
11 | /**
12 | * `ItemSeparator` component is used to display a separator between groups or
13 | * items in a menu.
14 | */
15 | export default function MenuItemSeparator({
16 | ...props
17 | }: MenuItemSeparatorProps) {
18 | return (
19 |
27 | )
28 | }
29 | MenuItemSeparator.displayName = 'MenuItemSeparator'
30 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Menu/SubMenu.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ArgTypes,
3 | Controls,
4 | Description,
5 | Meta,
6 | Primary,
7 | Subtitle,
8 | Title,
9 | } from '@storybook/blocks'
10 |
11 | import * as SubMenuStories from './SubMenu.stories'
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | ---
22 |
23 | ## Props
24 |
25 | On top of all the props, attributes and event handler you can set on a
26 | `` element, the component accepts the following props:
27 |
28 |
29 |
30 | ## Playground
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Menu/index.ts:
--------------------------------------------------------------------------------
1 | export { Elevations as MenuElevations } from '../Paper/Paper.constants.js'
2 | export {
3 | DEFAULT_ELEVATION as DEFAULT_MENU_ELEVATION,
4 | DEFAULT_ORIENTATION as DEFAULT_MENU_ORIENTATION,
5 | DEFAULT_SUB_MENU_ELEVATION as DEFAULT_MENU_SUB_MENU_ELEVATION,
6 | Orientations as MenuOrientations,
7 | } from './Menu.constants.js'
8 | export { default as Menu } from './Menu.js'
9 | export type {
10 | MenuItemGroupProps,
11 | MenuItemProps,
12 | MenuItemSeparatorProps,
13 | MenuProps,
14 | } from './Menu.types.js'
15 | export { default as MenuItem } from './MenuItem.js'
16 | export { default as MenuItemGroup } from './MenuItemGroup.js'
17 | export { default as MenuItemSeparator } from './MenuItemSeparator.js'
18 | export { default as SubMenu } from './SubMenu.js'
19 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Paper/Paper.constants.ts:
--------------------------------------------------------------------------------
1 | import type { ElementType } from 'react'
2 |
3 | export const GROUP_NAME = 'paper'
4 |
5 | export enum Elevations {
6 | Bordered = '1',
7 | Elevated = '2',
8 | Higher = '3',
9 | }
10 |
11 | export const DEFAULT_ELEVATION = Elevations.Bordered
12 |
13 | export const DEFAULT_ELEMENT: ElementType = 'div'
14 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Paper/Paper.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ArgTypes,
3 | Controls,
4 | Description,
5 | Meta,
6 | Primary,
7 | Stories,
8 | Subtitle,
9 | Title,
10 | } from '@storybook/blocks'
11 |
12 | import * as PaperStories from './Paper.stories'
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | ---
23 |
24 | ## Props
25 |
26 | On top of all the props, attributes and event handler you can set on a
27 | `` element, component accepts the following props:
28 |
29 |
30 |
31 |
32 |
33 | ## Playground
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Paper/Paper.types.ts:
--------------------------------------------------------------------------------
1 | import type { AllHTMLAttributes, ElementType, ReactNode } from 'react'
2 |
3 | import { Themes } from '@/constants'
4 |
5 | import { Elevations } from './Paper.constants'
6 |
7 | export interface PaperProps extends AllHTMLAttributes {
8 | /** The content of the paper. */
9 | children: ReactNode
10 | /** The HTML element to use to display your paper. */
11 | element?: ElementType
12 | /**
13 | * The elevation level of the paper.
14 | *
15 | * 1 (bordered) is a non elevated bordered block
16 | * 2 (elevated) is a lightly raised (small shadow) bordered block
17 | * 3 (higher) is a raised bordered block
18 | */
19 | elevation?: `${Elevations}`
20 | /**
21 | * Indicates to inline all styles (including resets, font, ...) or only the
22 | * needed ones.
23 | *
24 | * Only used with `inlineStyle` enabled.
25 | */
26 | fullStyle?: boolean
27 | /**
28 | * Indicates to inline the styles instead of using Tailwind CSS classes.
29 | *
30 | * The typical usage for this is when creating HTML for an email.
31 | */
32 | inlineStyle?: boolean
33 | /**
34 | * Force the theme of the paper.
35 | *
36 | * If none is given, it will use the one provided by the Context/Provider.
37 | */
38 | theme?: Themes
39 | }
40 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Paper/index.ts:
--------------------------------------------------------------------------------
1 | export {
2 | DEFAULT_ELEVATION as DEFAULT_PAPER_ELEVATION,
3 | Elevations as PaperElevations,
4 | } from './Paper.constants.js'
5 | export {
6 | default as Paper,
7 | elevationClassNames as paperElevationClassNames,
8 | elevationStyles as paperElevationStyles,
9 | } from './Paper.js'
10 | export type { PaperProps } from './Paper.types.js'
11 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Popover/Popover.constants.ts:
--------------------------------------------------------------------------------
1 | import { Elevations } from '@/components/Paper/Paper.constants'
2 |
3 | export const GROUP_NAME = 'popover'
4 |
5 | export const DEFAULT_ELEVATION = Elevations.Elevated
6 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Popover/Popover.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ArgTypes,
3 | Controls,
4 | Description,
5 | Meta,
6 | Primary,
7 | Subtitle,
8 | Title,
9 | } from '@storybook/blocks'
10 |
11 | import * as PopoverStories from './Popover.stories'
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | ---
22 |
23 | ## Props
24 |
25 | On top of all the props, attributes and event handler you can set on a
26 | `` element, the component accepts the following props:
27 |
28 |
29 |
30 | ## Playground
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Popover/index.ts:
--------------------------------------------------------------------------------
1 | export { Elevations as PopoverElevations } from '../Paper/Paper.constants.js'
2 | export { DEFAULT_ELEVATION as DEFAULT_POPOVER_ELEVATION } from './Popover.constants.js'
3 | export { default as Popover } from './Popover.js'
4 | export type {
5 | CombinedRefs as PopoverCombinedRefs,
6 | PopoverProps,
7 | } from './Popover.types.js'
8 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Progress/Progress.constants.ts:
--------------------------------------------------------------------------------
1 | export const GROUP_NAME = 'progress'
2 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Progress/Progress.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ArgTypes,
3 | Controls,
4 | Description,
5 | Meta,
6 | Primary,
7 | Subtitle,
8 | Title,
9 | } from '@storybook/blocks'
10 |
11 | import * as ProgressStories from './Progress.stories'
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | ---
22 |
23 | ## Props
24 |
25 | On top of all the props, attributes and event handler you can set on a
26 | `` element, the component accepts the following props:
27 |
28 |
29 |
30 | ## Playground
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Progress/Progress.stories.tsx:
--------------------------------------------------------------------------------
1 | import type { Meta, StoryObj } from '@storybook/react'
2 |
3 | import type { ComponentProps } from 'react'
4 |
5 | import { Progress } from '.'
6 |
7 | type ProgressProps = ComponentProps
8 |
9 | const meta: Meta = {
10 | args: {
11 | max: 100,
12 | value: 33,
13 | },
14 | component: Progress,
15 | parameters: {
16 | docs: {
17 | subtitle:
18 | '🧑🔧 Move, move, move! This is a 54-23 in progress - 04114 - Monsters University',
19 | },
20 | },
21 |
22 | title: 'Molecules/Progress',
23 | } satisfies Meta
24 |
25 | export default meta
26 | type Story = StoryObj
27 |
28 | export const Playground: Story = {}
29 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Progress/Progress.tsx:
--------------------------------------------------------------------------------
1 | import * as RxProgress from '@radix-ui/react-progress'
2 |
3 | import isFunction from 'lodash/fp/isFunction'
4 | import omit from 'lodash/fp/omit'
5 |
6 | import { PREFIX } from '@/constants'
7 | import { cj, cn } from '@/styles/helpers'
8 |
9 | import type { ProgressProps } from './Progress.types'
10 |
11 | import { GROUP_NAME } from './Progress.constants'
12 |
13 | /**
14 | * `Progress` component is used to display a progression to the user.
15 | *
16 | * See https://www.radix-ui.com/primitives/docs/components/progress for more
17 | * information.
18 | */
19 | export const Progress = ({
20 | getValueLabel,
21 | max = 100,
22 | value = 0,
23 | ...props
24 | }: ProgressProps) => (
25 |
36 |
46 |
47 | )
48 | Progress.displayName = 'Progress'
49 |
50 | export default Progress
51 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Progress/Progress.types.ts:
--------------------------------------------------------------------------------
1 | import { AllHTMLAttributes } from 'react'
2 |
3 | export interface ProgressProps extends AllHTMLAttributes {
4 | /**
5 | * A function to get the accessible label text representing the current value
6 | * in a human-readable format.
7 | *
8 | * If not provided, the value label will be read as the numeric value as a
9 | * percentage of the max value.
10 | */
11 | getValueLabel?: (value: number, max: number) => string
12 | /** The maximum progress value. */
13 | max?: number
14 | /** The current progress value. */
15 | value?: number
16 | }
17 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Progress/index.ts:
--------------------------------------------------------------------------------
1 | export { default as Progress } from './Progress.js'
2 | export type { ProgressProps } from './Progress.types.js'
3 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/ScrollArea/ScrollArea.constants.ts:
--------------------------------------------------------------------------------
1 | export const GROUP_NAME = 'scroll-area'
2 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/ScrollArea/ScrollArea.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ArgTypes,
3 | Controls,
4 | Description,
5 | Meta,
6 | Primary,
7 | Stories,
8 | Subtitle,
9 | Title,
10 | } from '@storybook/blocks'
11 |
12 | import * as ScrollAreaStories from './ScrollArea.stories'
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | ---
23 |
24 | ## Props
25 |
26 | On top of all the props, attributes and event handler you can set on a
27 | `` element, component accepts the following props:
28 |
29 |
30 |
31 |
32 |
33 | ## Playground
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/ScrollArea/index.ts:
--------------------------------------------------------------------------------
1 | export { default as ScrollArea } from './ScrollArea.js'
2 | export type { ScrollAreaProps } from './ScrollArea.types.js'
3 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Select/Select.constants.ts:
--------------------------------------------------------------------------------
1 | export const GROUP_NAME = 'select'
2 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Select/Select.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ArgTypes,
3 | Controls,
4 | Description,
5 | Meta,
6 | Primary,
7 | Subtitle,
8 | Title,
9 | } from '@storybook/blocks'
10 |
11 | import * as SelectStories from './Select.stories'
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | ---
22 |
23 | ## Props
24 |
25 | On top of all the props, attributes and event handler you can set on a
26 | `` element, the component accepts the following props:
27 |
28 |
29 |
30 | ## Playground
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Select/SelectEmpty.mdx:
--------------------------------------------------------------------------------
1 | import { Description, Meta, Primary, Subtitle, Title } from '@storybook/blocks'
2 |
3 | import * as SelectEmptyStories from './SelectEmpty.stories'
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | ---
14 |
15 | ## Props
16 |
17 | You can pass any props, attributes and event handler you can set on a
18 | `` element.
19 |
20 | ## Playground
21 |
22 |
23 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Select/SelectEmpty.stories.tsx:
--------------------------------------------------------------------------------
1 | import type { Meta, StoryObj } from '@storybook/react'
2 |
3 | import type { ComponentProps } from 'react'
4 |
5 | import { Select, SelectEmpty } from '.'
6 |
7 | type SelectEmptyProps = ComponentProps
8 |
9 | const meta: Meta = {
10 | args: {
11 | children: 'No results! Sorry about that!',
12 | },
13 | argTypes: {
14 | children: {
15 | control: 'text',
16 | },
17 | },
18 | component: SelectEmpty,
19 | parameters: {
20 | chromatic: { delay: 2000 },
21 | },
22 |
23 | title: 'Molecules/Select/SelectEmpty',
24 | } satisfies Meta
25 |
26 | export default meta
27 | type Story = StoryObj
28 |
29 | export const Playground: Story = {
30 | render: ({ children }) => (
31 |
32 |
35 |
36 | ),
37 | }
38 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Select/SelectGroupContext.ts:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { createContext } from 'react'
4 |
5 | export const SelectGroupContext = createContext<{
6 | disabled: boolean
7 | }>({ disabled: false })
8 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Select/SelectItem.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ArgTypes,
3 | Controls,
4 | Description,
5 | Meta,
6 | Primary,
7 | Subtitle,
8 | Title,
9 | } from '@storybook/blocks'
10 |
11 | import * as SelectItemStories from './SelectItem.stories'
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | ---
22 |
23 | ## Props
24 |
25 | On top of all the props, attributes and event handler you can set on a
26 | `` element, the component accepts the following props:
27 |
28 |
29 |
30 | ## Playground
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Select/SelectItem.stories.tsx:
--------------------------------------------------------------------------------
1 | import type { Meta, StoryObj } from '@storybook/react'
2 |
3 | import { action } from '@storybook/addon-actions'
4 |
5 | import type { ComponentProps } from 'react'
6 |
7 | import { Select, SelectItem } from '.'
8 |
9 | type SelectItemProps = ComponentProps
10 |
11 | const meta: Meta = {
12 | args: {
13 | children: 'Jar Jar Binks',
14 | disabled: false,
15 | value: 'jar-jar-binks',
16 | },
17 | argTypes: {
18 | children: { control: 'text' },
19 | },
20 | component: SelectItem,
21 |
22 | title: 'Molecules/Select/SelectItem',
23 | } satisfies Meta
24 |
25 | export default meta
26 | type Story = StoryObj
27 |
28 | export const Playground: Story = {
29 | render: ({ children, disabled = false, value }) => (
30 |
31 |
36 |
37 | ),
38 | }
39 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Select/SelectItemGroup.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ArgTypes,
3 | Controls,
4 | Description,
5 | Meta,
6 | Primary,
7 | Subtitle,
8 | Title,
9 | } from '@storybook/blocks'
10 |
11 | import * as SelectItemGroupStories from './SelectItemGroup.stories'
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | ---
22 |
23 | ## Props
24 |
25 | On top of all the props, attributes and event handler you can set on a
26 | `` element, the component accepts the following props:
27 |
28 |
29 |
30 | ## Playground
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Select/SelectItemGroup.stories.tsx:
--------------------------------------------------------------------------------
1 | import type { Meta, StoryObj } from '@storybook/react'
2 |
3 | import { action } from '@storybook/addon-actions'
4 |
5 | import type { ComponentProps } from 'react'
6 |
7 | import { Select, SelectItem, SelectItemGroup } from '.'
8 |
9 | type SelectItemGroupProps = ComponentProps
10 |
11 | const meta: Meta = {
12 | args: {
13 | disabled: false,
14 | label: 'Jedis',
15 | },
16 | argTypes: {
17 | children: {
18 | control: false,
19 | table: {
20 | type: {
21 | summary:
22 | 'SelectItem | SelectItemSeparator | Array',
23 | },
24 | },
25 | },
26 | },
27 | component: SelectItemGroup,
28 |
29 | title: 'Molecules/Select/SelectItemGroup',
30 | } satisfies Meta
31 |
32 | export default meta
33 | type Story = StoryObj
34 |
35 | export const Playground: Story = {
36 | render: ({ disabled = false, label }) => (
37 |
38 |
45 |
46 | ),
47 | }
48 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Select/SelectItemSeparator.mdx:
--------------------------------------------------------------------------------
1 | import { Description, Meta, Primary, Subtitle, Title } from '@storybook/blocks'
2 |
3 | import * as SelectItemSeparatorStories from './SelectItemSeparator.stories'
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | ---
14 |
15 | ## Props
16 |
17 | You can pass any props, attributes and event handler you can set on a
18 | `` element.
19 |
20 | ## Playground
21 |
22 |
23 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Select/SelectItemSeparator.stories.tsx:
--------------------------------------------------------------------------------
1 | import type { Meta, StoryObj } from '@storybook/react'
2 |
3 | import { action } from '@storybook/addon-actions'
4 |
5 | import type { ComponentProps } from 'react'
6 |
7 | import { Select, SelectItem, SelectItemSeparator } from '.'
8 |
9 | type SelectItemSeparatorProps = ComponentProps
10 |
11 | const meta: Meta = {
12 | component: SelectItemSeparator,
13 |
14 | title: 'Molecules/Select/SelectItemSeparator',
15 | } satisfies Meta
16 |
17 | export default meta
18 | type Story = StoryObj
19 |
20 | export const Playground: Story = {
21 | render: () => (
22 |
23 |
28 |
29 | ),
30 | }
31 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Select/index.ts:
--------------------------------------------------------------------------------
1 | export { default as SelectItemSeparator } from '../Dropdown/DropdownItemSeparator.js'
2 | export { default as Select } from './Select.js'
3 | export type {
4 | SelectItemGroupProps,
5 | SelectItemProps,
6 | SelectItemSeparatorProps,
7 | SelectProps,
8 | CombinedRefs as SelectRefs,
9 | } from './Select.types.js'
10 | export { default as SelectEmpty } from './SelectEmpty.js'
11 | export { default as SelectItem } from './SelectItem.js'
12 | export { default as SelectItemGroup } from './SelectItemGroup.js'
13 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Skeleton/Skeleton.constants.ts:
--------------------------------------------------------------------------------
1 | export const GROUP_NAME = 'skeleton'
2 |
3 | export enum Colors {
4 | Blue = 'blue',
5 | Green = 'green',
6 | Pink = 'pink',
7 | Purple = 'purple',
8 | Yellow = 'yellow',
9 |
10 | // Greyscale.
11 | Black = 'black',
12 | DarkGrey = 'dark-grey',
13 | Grey = 'grey',
14 | LightGrey = 'light-grey',
15 | White = 'white',
16 | }
17 |
18 | export const DEFAULT_COLOR = Colors.Grey
19 |
20 | export enum Shapes {
21 | Circle = 'circle',
22 | Rectangle = 'rectangle',
23 | RoundedRectangle = 'roundedRectangle',
24 | Square = 'square',
25 | }
26 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Skeleton/Skeleton.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ArgTypes,
3 | Controls,
4 | Description,
5 | Meta,
6 | Primary,
7 | Stories,
8 | Subtitle,
9 | Title,
10 | } from '@storybook/blocks'
11 |
12 | import * as SkeletonStories from './Skeleton.stories'
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | ---
23 |
24 | ## Props
25 |
26 | On top of all the props, attributes and event handler you can set on a
27 | `` element, the component accepts the following props:
28 |
29 |
30 |
31 |
32 |
33 | ## Playground
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Skeleton/Skeleton.types.ts:
--------------------------------------------------------------------------------
1 | import type { AllHTMLAttributes, ReactNode } from 'react'
2 |
3 | import { Colors, Shapes } from './Skeleton.constants'
4 |
5 | export interface SkeletonProps extends AllHTMLAttributes {
6 | /** The shape of the skeleton. */
7 | shape: `${Shapes}`
8 | /** The optional content you may want to display inside of the skeleton. */
9 | children?: ReactNode
10 | /** The color of the skeleton. */
11 | color?: `${Colors}`
12 | }
13 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Skeleton/index.ts:
--------------------------------------------------------------------------------
1 | export {
2 | DEFAULT_COLOR as DEFAULT_SKELETON_COLOR,
3 | Colors as SkeletonColors,
4 | Shapes as SkeletonShapes,
5 | } from './Skeleton.constants.js'
6 | export { default as Skeleton } from './Skeleton.js'
7 | export type { SkeletonProps } from './Skeleton.types.js'
8 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Slider/Slider.constants.ts:
--------------------------------------------------------------------------------
1 | export const GROUP_NAME = 'slider'
2 |
3 | export enum Orientations {
4 | Horizontal = 'horizontal',
5 | Vertical = 'vertical',
6 | }
7 |
8 | export const DEFAULT_ORIENTATION = Orientations.Horizontal
9 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Slider/Slider.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ArgTypes,
3 | Controls,
4 | Description,
5 | Meta,
6 | Primary,
7 | Subtitle,
8 | Title,
9 | } from '@storybook/blocks'
10 |
11 | import * as SliderStories from './Slider.stories'
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | ---
22 |
23 | ## Props
24 |
25 | On top of all the props, attributes and event handler you can set on a
26 | `` element, the component accepts the following props:
27 |
28 |
29 |
30 | ## Playground
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Slider/index.ts:
--------------------------------------------------------------------------------
1 | export {
2 | DEFAULT_ORIENTATION as DEFAULT_SLIDER_ORIENTATION,
3 | Orientations as SliderOrientations,
4 | } from './Slider.constants.js'
5 | export { default as Slider } from './Slider.js'
6 |
7 | export type { SliderProps } from './Slider.types.js'
8 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Stepper/Stepper.constants.ts:
--------------------------------------------------------------------------------
1 | export const GROUP_NAME = 'stepper'
2 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Stepper/Stepper.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ArgTypes,
3 | Controls,
4 | Description,
5 | Meta,
6 | Primary,
7 | Stories,
8 | Subtitle,
9 | Title,
10 | } from '@storybook/blocks'
11 |
12 | import * as StepperStories from './Stepper.stories'
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | ---
23 |
24 | ## Props
25 |
26 | On top of all the props, attributes and event handler you can set on a
27 | `` element, the component accepts the following props:
28 |
29 |
30 |
31 |
32 |
33 | ## Playground
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Stepper/Stepper.stories.tsx:
--------------------------------------------------------------------------------
1 | import type { Meta, StoryObj } from '@storybook/react'
2 |
3 | import type { ComponentProps } from 'react'
4 |
5 | import { Stepper } from '.'
6 |
7 | type StepperProps = ComponentProps
8 |
9 | const meta: Meta = {
10 | args: {
11 | current: 1,
12 | currentAs: 'step',
13 | length: 3,
14 | max: 100,
15 | value: 33,
16 | },
17 | component: Stepper,
18 | parameters: {
19 | docs: { subtitle: '🎈 Is this step three or step five? - Russel - Up' },
20 | },
21 |
22 | title: 'Molecules/Stepper',
23 | } satisfies Meta
24 |
25 | export default meta
26 | type Story = StoryObj
27 |
28 | export const Playground: Story = {}
29 |
30 | export const Simple: Story = {
31 | render: () => ,
32 | }
33 |
34 | export const Progress: Story = {
35 | render: () => (
36 |
37 | ),
38 | }
39 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Stepper/Stepper.types.ts:
--------------------------------------------------------------------------------
1 | import { AllHTMLAttributes } from 'react'
2 |
3 | export interface StepperProps extends AllHTMLAttributes {
4 | /** The number of steps. */
5 | length: number
6 | /** The current step. */
7 | current?: number
8 | /**
9 | * Indicates how you want to display the current step.
10 | *
11 | * - `step`: The current step will be displayed as a fixed step.
12 | * - `progress`: The current step will be displayed as a progress bar.
13 | */
14 | currentAs?: 'progress' | 'step'
15 | /**
16 | * A function to get the accessible label text representing the current value
17 | * in a human-readable format.
18 | *
19 | * If not provided, the value label will be read as "/".
20 | */
21 | getValueLabel?: (current: number, length: number) => string
22 | /**
23 | * When displaying the current step as a progress bar, the maximum value of
24 | * the progress bar.
25 | */
26 | max?: number
27 | /**
28 | * When displaying the current step as a progress bar, the current value of
29 | * the progress bar.
30 | */
31 | value?: number
32 | }
33 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Stepper/index.ts:
--------------------------------------------------------------------------------
1 | export { default as Stepper } from './Stepper.js'
2 | export type { StepperProps } from './Stepper.types.js'
3 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Switch/Switch.constants.ts:
--------------------------------------------------------------------------------
1 | export const GROUP_NAME = 'switch'
2 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Switch/Switch.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ArgTypes,
3 | Controls,
4 | Description,
5 | Meta,
6 | Primary,
7 | Stories,
8 | Subtitle,
9 | Title,
10 | } from '@storybook/blocks'
11 |
12 | import * as SwitchStories from './Switch.stories'
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | ---
23 |
24 | ## Props
25 |
26 | On top of all the props, attributes and event handler you can set on a
27 | `` element, the component accepts the following props:
28 |
29 |
30 |
31 |
32 |
33 | ## Playground
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Switch/index.ts:
--------------------------------------------------------------------------------
1 | export { default as Switch } from './Switch.js'
2 | export type { SwitchProps } from './Switch.types.js'
3 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Tabs/Tab.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ArgTypes,
3 | Controls,
4 | Description,
5 | Meta,
6 | Primary,
7 | Stories,
8 | Subtitle,
9 | Title,
10 | } from '@storybook/blocks'
11 |
12 | import * as TabStories from './Tab.stories'
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | ---
23 |
24 | ## Props
25 |
26 | On top of all the props, attributes and event handler you can set on a
27 | `` element, the component accepts the following props:
28 |
29 |
30 |
31 |
32 |
33 | ## Playground
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Tabs/TabContent.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ArgTypes,
3 | Controls,
4 | Description,
5 | Meta,
6 | Primary,
7 | Stories,
8 | Subtitle,
9 | Title,
10 | } from '@storybook/blocks'
11 |
12 | import * as TabContentStories from './TabContent.stories'
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | ---
23 |
24 | ## Props
25 |
26 | On top of all the props, attributes and event handler you can set on a
27 | `` element, the component accepts the following props:
28 |
29 |
30 |
31 |
32 |
33 | ## Playground
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Tabs/TabContent.tsx:
--------------------------------------------------------------------------------
1 | import * as RxTabs from '@radix-ui/react-tabs'
2 |
3 | import { type ForwardedRef, forwardRef } from 'react'
4 |
5 | import omit from 'lodash/fp/omit'
6 |
7 | import { PREFIX } from '@/constants'
8 | import { cn } from '@/styles/helpers'
9 |
10 | import type { TabContentProps } from './Tabs.types'
11 |
12 | import { GROUP_NAME } from './Tabs.constants'
13 |
14 | /**
15 | * `TabContent` component is used to display the content of a tab inside of a
16 | * `Tabs` component.
17 | *
18 | * See https://www.radix-ui.com/primitives/docs/components/tabs#content for more
19 | * information.
20 | */
21 | export const TabContent = forwardRef(
22 | (
23 | { children, forceMount = false, name, ...props }: TabContentProps,
24 | ref: ForwardedRef,
25 | ) => (
26 |
33 | {children}
34 |
35 | ),
36 | )
37 | TabContent.displayName = 'TabContent'
38 |
39 | export default TabContent
40 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Tabs/Tabs.constants.ts:
--------------------------------------------------------------------------------
1 | export const GROUP_NAME = 'tabs'
2 |
3 | export enum Orientations {
4 | Horizontal = 'horizontal',
5 | Vertical = 'vertical',
6 | }
7 |
8 | export const DEFAULT_ORIENTATION = Orientations.Horizontal
9 |
10 | export enum Positions {
11 | End = 'end',
12 | Start = 'start',
13 | }
14 |
15 | export const DEFAULT_POSITION = Positions.Start
16 |
17 | export enum Sizes {
18 | Large = 'large',
19 | Medium = 'medium',
20 | Small = 'small',
21 | }
22 |
23 | export const DEFAULT_SIZE = Sizes.Small
24 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Tabs/Tabs.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ArgTypes,
3 | Controls,
4 | Description,
5 | Meta,
6 | Primary,
7 | Stories,
8 | Subtitle,
9 | Title,
10 | } from '@storybook/blocks'
11 |
12 | import * as TabsStories from './Tabs.stories'
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | ---
23 |
24 | ## Props
25 |
26 | On top of all the props, attributes and event handler you can set on a
27 | `` element, the component accepts the following props:
28 |
29 |
30 |
31 |
32 |
33 | ## Playground
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Tabs/index.ts:
--------------------------------------------------------------------------------
1 | export { default as Tab } from './Tab.js'
2 | export { default as TabContent } from './TabContent.js'
3 | export {
4 | DEFAULT_SIZE as DEFAULT_TAB_SIZE,
5 | DEFAULT_ORIENTATION as DEFAULT_TABS_ORIENTATION,
6 | DEFAULT_POSITION as DEFAULT_TABS_POSITION,
7 | Sizes as TabSizes,
8 | Orientations as TabsOrientations,
9 | Positions as TabsPositions,
10 | } from './Tabs.constants.js'
11 | export { default as Tabs } from './Tabs.js'
12 | export type { TabContentProps, TabProps, TabsProps } from './Tabs.types.js'
13 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Tag/Tag.constants.ts:
--------------------------------------------------------------------------------
1 | import { Variants as TypographyVariants } from '@/components/Typography/Typography.constants'
2 |
3 | export const GROUP_NAME = 'tag'
4 |
5 | export enum Sizes {
6 | // Small.
7 | S = 's',
8 |
9 | // Medium.
10 | M = 'm',
11 | }
12 |
13 | export const DEFAULT_SIZE = Sizes.S
14 |
15 | export const sizeToTypographyVariant: Record = {
16 | [Sizes.S]: TypographyVariants.CaptionMedian,
17 |
18 | [Sizes.M]: TypographyVariants.Body1,
19 | }
20 |
21 | export enum Colors {
22 | Blue = 'blue',
23 | Green = 'green',
24 | Pink = 'pink',
25 | Purple = 'purple',
26 | White = 'white',
27 | Yellow = 'yellow',
28 | }
29 |
30 | export const DEFAULT_COLOR = Colors.Pink
31 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Tag/Tag.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ArgTypes,
3 | Controls,
4 | Description,
5 | Meta,
6 | Primary,
7 | Stories,
8 | Subtitle,
9 | Title,
10 | } from '@storybook/blocks'
11 |
12 | import * as TagStories from './Tag.stories'
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | ---
23 |
24 | ## Props
25 |
26 | On top of all the props, attributes and event handler you can set on a
27 | `` element, the component accepts the following props:
28 |
29 |
30 |
31 |
32 |
33 | ## Playground
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Tag/Tag.types.ts:
--------------------------------------------------------------------------------
1 | import type { AllHTMLAttributes, ReactNode } from 'react'
2 |
3 | import { Colors, Sizes } from './Tag.constants'
4 |
5 | export interface TagProps
6 | extends Omit, 'size'> {
7 | /**
8 | * The content of the tag.
9 | *
10 | * Use this for complex content where a string (passed to the `label` prop) is
11 | * not enough.
12 | */
13 | children?: ReactNode
14 | /** The color of the tag to use. */
15 | color?: `${Colors}`
16 | /** Indicates if the tag is disabled. */
17 | disabled?: boolean
18 | /** Indicates if the tag should take all the available width. */
19 | fullWidth?: boolean
20 | /**
21 | * The content of the tag.
22 | *
23 | * Use this when you only need to display text in a tag.
24 | * If you need more complex content, use the `children` prop.
25 | *
26 | * When using the `children` prop, you can use this prop to set a simple
27 | * textual representation of the item that will be used as the `aria-label`
28 | * and `title` for the tag.
29 | */
30 | label?: string
31 | /** The size of the tag. */
32 | size?: `${Sizes}`
33 | }
34 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Tag/index.ts:
--------------------------------------------------------------------------------
1 | export {
2 | DEFAULT_COLOR as DEFAULT_TAG_COLOR,
3 | DEFAULT_SIZE as DEFAULT_TAG_SIZE,
4 | Colors as TagColors,
5 | Sizes as TagSizes,
6 | sizeToTypographyVariant as tagSizeToTypographyVariant,
7 | } from './Tag.constants.js'
8 | export { default as Tag } from './Tag.js'
9 | export type { TagProps } from './Tag.types.js'
10 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Textarea/Textarea.constants.ts:
--------------------------------------------------------------------------------
1 | export const GROUP_NAME = 'input-textarea'
2 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Textarea/Textarea.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ArgTypes,
3 | Controls,
4 | Description,
5 | Meta,
6 | Primary,
7 | Stories,
8 | Subtitle,
9 | Title,
10 | } from '@storybook/blocks'
11 |
12 | import * as TextareaStories from './Textarea.stories'
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | ---
23 |
24 | ## Props
25 |
26 | On top of all the props, attributes and event handler you can set on a
27 | `` component (and thus a `` element), the
28 | component accepts the following props:
29 |
30 |
31 |
32 |
33 |
34 | ## Playground
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Textarea/index.ts:
--------------------------------------------------------------------------------
1 | export { default as Textarea } from './Textarea.js'
2 | export type { TextareaProps } from './Textarea.types.js'
3 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Toggle/Toggle.constants.ts:
--------------------------------------------------------------------------------
1 | export const GROUP_NAME = 'toggle'
2 |
3 | export enum Variants {
4 | Primary = 'primary',
5 | }
6 |
7 | export const DEFAULT_VARIANT = Variants.Primary
8 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Toggle/Toggle.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ArgTypes,
3 | Controls,
4 | Description,
5 | Meta,
6 | Primary,
7 | Stories,
8 | Subtitle,
9 | Title,
10 | } from '@storybook/blocks'
11 |
12 | import * as ToggleStories from './Toggle.stories'
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | ---
23 |
24 | ## Props
25 |
26 | On top of all the props, attributes and event handler you can set on a
27 | `` element, the component accepts the following props:
28 |
29 |
30 |
31 |
32 |
33 | ## Playground
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Toggle/index.ts:
--------------------------------------------------------------------------------
1 | export {
2 | DEFAULT_VARIANT as DEFAULT_TOGGLE_VARIANT,
3 | Variants as ToggleVariants,
4 | } from './Toggle.constants.js'
5 | export { default as Toggle } from './Toggle.js'
6 | export type { ToggleProps } from './Toggle.types.js'
7 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/ToggleGroup/ToggleGroup.constants.ts:
--------------------------------------------------------------------------------
1 | export const GROUP_NAME = 'toggle-group'
2 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/ToggleGroup/ToggleGroup.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ArgTypes,
3 | Controls,
4 | Description,
5 | Meta,
6 | Primary,
7 | Stories,
8 | Subtitle,
9 | Title,
10 | } from '@storybook/blocks'
11 |
12 | import * as ToggleGroupStories from './ToggleGroup.stories'
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | ---
23 |
24 | ## Props
25 |
26 | On top of all the props, attributes and event handler you can set on a
27 | `` element, the component accepts the following props:
28 |
29 |
30 |
31 |
32 |
33 | ## Playground
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/ToggleGroup/ToggleGroupContext.ts:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { createContext } from 'react'
4 |
5 | import { DEFAULT_VARIANT, Variants } from '@/components/Toggle/Toggle.constants'
6 |
7 | export const ToggleGroupContext = createContext<{
8 | disabled: boolean
9 | variant: `${Variants}`
10 | }>({ disabled: false, variant: DEFAULT_VARIANT })
11 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/ToggleGroup/ToggleGroupItem.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ArgTypes,
3 | Controls,
4 | Description,
5 | Meta,
6 | Primary,
7 | Subtitle,
8 | Title,
9 | } from '@storybook/blocks'
10 |
11 | import * as ToggleGroupItem from './ToggleGroupItem.stories'
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | ---
22 |
23 | ## Props
24 |
25 | On top of all the props, attributes and event handler you can set on a
26 | `` element, the component accepts the following props:
27 |
28 |
29 |
30 | ## Playground
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/ToggleGroup/index.ts:
--------------------------------------------------------------------------------
1 | export { Variants as ToggleGroupVariants } from '../Toggle/Toggle.constants.js'
2 | export { default as ToggleGroup } from './ToggleGroup.js'
3 | export type {
4 | ToggleGroupItemProps,
5 | ToggleGroupProps,
6 | } from './ToggleGroup.types.js'
7 | export { default as ToggleGroupItem } from './ToggleGroupItem.js'
8 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Toolbar/Toolbar.constants.ts:
--------------------------------------------------------------------------------
1 | import { Elevations } from '@/components/Paper/Paper.constants'
2 |
3 | export const GROUP_NAME = 'toolbar'
4 |
5 | export enum Orientations {
6 | Horizontal = 'horizontal',
7 | Vertical = 'vertical',
8 | }
9 |
10 | export const DEFAULT_ORIENTATION = Orientations.Horizontal
11 |
12 | export const DEFAULT_ELEVATION = Elevations.Elevated
13 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Toolbar/Toolbar.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ArgTypes,
3 | Controls,
4 | Description,
5 | Meta,
6 | Primary,
7 | Stories,
8 | Subtitle,
9 | Title,
10 | } from '@storybook/blocks'
11 |
12 | import * as ToolbarStories from './Toolbar.stories'
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | ---
23 |
24 | ## Props
25 |
26 | On top of all the props, attributes and event handler you can set on a
27 | `` element, the component accepts the following props:
28 |
29 |
30 |
31 |
32 |
33 | ## Playground
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Toolbar/ToolbarButton.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ArgTypes,
3 | Controls,
4 | Description,
5 | Meta,
6 | Primary,
7 | Subtitle,
8 | Title,
9 | } from '@storybook/blocks'
10 |
11 | import * as ToolbarButtonStories from './ToolbarButton.stories'
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | ---
22 |
23 | ## Props
24 |
25 | On top of all the props, attributes and event handler you can set on a
26 | `` element, the component accepts the following props:
27 |
28 |
29 |
30 | ## Playground
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Toolbar/ToolbarContext.ts:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { createContext } from 'react'
4 |
5 | import { DEFAULT_ORIENTATION, Orientations } from './Toolbar.constants'
6 |
7 | export const ToolbarContext = createContext<{
8 | disabled: boolean
9 | orientation: `${Orientations}`
10 | }>({
11 | disabled: false,
12 | orientation: DEFAULT_ORIENTATION,
13 | })
14 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Toolbar/ToolbarDropdown.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ArgTypes,
3 | Controls,
4 | Description,
5 | Meta,
6 | Primary,
7 | Stories,
8 | Subtitle,
9 | Title,
10 | } from '@storybook/blocks'
11 |
12 | import * as ToolbarDropdownStories from './ToolbarDropdown.stories'
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | ---
23 |
24 | ## Props
25 |
26 | On top of all the props, attributes and event handler you can set on a
27 | `` component (and thus on a`` element) (except for
28 | `condensed` and the `trigger`), you can also pass the 'active', 'icon',
29 | 'iconOnly', 'iconPosition' and 'label' props of a `` component
30 | that will be used as the trigger of the dropdown.
31 | Also, you can pass the following props:
32 |
33 |
34 |
35 |
36 |
37 | ## Playground
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Toolbar/ToolbarDropdownItem.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ArgTypes,
3 | Controls,
4 | Description,
5 | Meta,
6 | Primary,
7 | Subtitle,
8 | Title,
9 | } from '@storybook/blocks'
10 |
11 | import * as ToolbarDropdownItemStories from './ToolbarDropdownItem.stories'
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | ---
22 |
23 | ## Props
24 |
25 | On top of all the props, attributes and event handler you can set on a
26 | `` component (and thus a `` element), the component
27 | accepts the following props:
28 |
29 |
30 |
31 | ## Playground
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Toolbar/ToolbarDropdownItemGroup.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ArgTypes,
3 | Controls,
4 | Description,
5 | Meta,
6 | Primary,
7 | Subtitle,
8 | Title,
9 | } from '@storybook/blocks'
10 |
11 | import * as ToolbarDropdownItemGroupStories from './ToolbarDropdownItemGroup.stories'
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | ---
22 |
23 | ## Props
24 |
25 | On top of all the props, attributes and event handler you can set on a
26 | `` component (and thus a `` element), the component
27 | accepts the following props:
28 |
29 |
30 |
31 | ## Playground
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Toolbar/ToolbarDropdownItemSeparator.mdx:
--------------------------------------------------------------------------------
1 | import { Description, Meta, Primary, Subtitle, Title } from '@storybook/blocks'
2 |
3 | import * as ToolbarDropdownItemSeparatortories from './ToolbarDropdownItemSeparator.stories'
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | ---
14 |
15 | ## Props
16 |
17 | You can set for this component all the props, attributes and event handler you
18 | can set on a `` component (and thus a ``
19 | element).
20 |
21 | ## Playground
22 |
23 |
24 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Toolbar/ToolbarDropdownItemSeparator.stories.tsx:
--------------------------------------------------------------------------------
1 | import type { Meta, StoryObj } from '@storybook/react'
2 |
3 | import { UilUserCircle as UserIcon } from '@tooni/iconscout-unicons-react'
4 |
5 | import type { ComponentProps } from 'react'
6 |
7 | import ToolbarDropdownItem from '@/components/Dropdown/DropdownItem'
8 | import ToolbarDropdownItemSeparator from '@/components/Dropdown/DropdownItemSeparator'
9 |
10 | import Toolbar from './Toolbar'
11 | import ToolbarDropdown from './ToolbarDropdown'
12 |
13 | type ToolbarDropdownItemSeparatorProps = ComponentProps<
14 | typeof ToolbarDropdownItemSeparator
15 | >
16 |
17 | const meta: Meta = {
18 | component: ToolbarDropdownItemSeparator,
19 | parameters: {
20 | chromatic: { delay: 2000 },
21 | },
22 |
23 | title: 'Molecules/Toolbar/ToolbarDropdown/ToolbarDropdownItemSeparator',
24 | } satisfies Meta
25 |
26 | export default meta
27 | type Story = StoryObj
28 |
29 | export const Playground: Story = {
30 | render: () => (
31 |
32 |
33 | }
35 | iconOnly
36 | label="Star wars characters"
37 | >
38 |
39 |
40 |
41 |
42 |
43 |
44 | ),
45 | }
46 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Toolbar/ToolbarSeparator.mdx:
--------------------------------------------------------------------------------
1 | import { Description, Meta, Primary, Subtitle, Title } from '@storybook/blocks'
2 |
3 | import * as ToolbarSeparatortories from './ToolbarSeparator.stories'
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | ---
14 |
15 | ## Props
16 |
17 | You can pass any props, attributes and event handler you can set on a
18 | `` element.
19 |
20 | ## Playground
21 |
22 |
23 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Toolbar/ToolbarSeparator.stories.tsx:
--------------------------------------------------------------------------------
1 | import type { Meta, StoryObj } from '@storybook/react'
2 |
3 | import type { ComponentProps } from 'react'
4 |
5 | import { Toolbar, ToolbarButton, ToolbarSeparator } from '.'
6 |
7 | type ToolbarSeparatorProps = ComponentProps
8 |
9 | const meta: Meta = {
10 | component: ToolbarSeparator,
11 | parameters: {
12 | chromatic: { delay: 2000 },
13 | },
14 |
15 | title: 'Molecules/Toolbar/ToolbarSeparator',
16 | } satisfies Meta
17 |
18 | export default meta
19 | type Story = StoryObj
20 |
21 | export const Playground: Story = {
22 | render: () => (
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 | ),
37 | }
38 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Toolbar/ToolbarSeparator.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import * as RxToolbar from '@radix-ui/react-toolbar'
4 |
5 | import { useContext } from 'react'
6 |
7 | import omit from 'lodash/fp/omit'
8 |
9 | import { PREFIX } from '@/constants'
10 | import { cn } from '@/styles/helpers'
11 |
12 | import { GROUP_NAME, Orientations } from './Toolbar.constants'
13 | import { ToolbarSeparatorProps } from './Toolbar.types'
14 | import { ToolbarContext } from './ToolbarContext'
15 |
16 | /**
17 | * `ToolbarSeparator` component is used to display a separator between groups or
18 | * items in a toolbar.
19 | */
20 | export default function ToolbarSeparator({ ...props }: ToolbarSeparatorProps) {
21 | const { orientation } = useContext(ToolbarContext)
22 |
23 | return (
24 |
34 | )
35 | }
36 | ToolbarSeparator.displayName = 'ToolbarSeparator'
37 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Toolbar/index.ts:
--------------------------------------------------------------------------------
1 | export { default as ToolbarDropdownItem } from '../Dropdown/DropdownItem.js'
2 | export { default as ToolbarDropdownItemGroup } from '../Dropdown/DropdownItemGroup.js'
3 | export { default as ToolbarDropdownItemSeparator } from '../Dropdown/DropdownItemSeparator.js'
4 | export { Elevations as ToolbarElevations } from '../Paper/Paper.constants.js'
5 | export {
6 | DEFAULT_ELEVATION as DEFAULT_TOOLBAR_ELEVATION,
7 | DEFAULT_ORIENTATION as DEFAULT_TOOLBAR_ORIENTATION,
8 | Orientations as ToolbarOrientations,
9 | } from './Toolbar.constants.js'
10 | export { default as Toolbar } from './Toolbar.js'
11 | export type { ToolbarButtonProps, ToolbarProps } from './Toolbar.types.js'
12 | export { default as ToolbarButton } from './ToolbarButton.js'
13 | export { default as ToolbarDropdown } from './ToolbarDropdown.js'
14 | export { default as ToolbarSeparator } from './ToolbarSeparator.js'
15 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Tooltip/Tooltip.constants.ts:
--------------------------------------------------------------------------------
1 | export const GROUP_NAME = 'tooltip'
2 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Tooltip/Tooltip.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ArgTypes,
3 | Controls,
4 | Description,
5 | Meta,
6 | Primary,
7 | Stories,
8 | Subtitle,
9 | Title,
10 | } from '@storybook/blocks'
11 |
12 | import * as TooltipStories from './Tooltip.stories'
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | ---
23 |
24 | ## Props
25 |
26 | On top of all the props, attributes and event handler you can set on a
27 | `` element, component accepts the following props:
28 |
29 |
30 |
31 |
32 |
33 | ## Playground
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Tooltip/Tooltip.stories.tsx:
--------------------------------------------------------------------------------
1 | import type { Meta, StoryObj } from '@storybook/react'
2 |
3 | import { fn } from '@storybook/test'
4 | import { UilEllipsisV as MoreMenuIcon } from '@tooni/iconscout-unicons-react'
5 |
6 | import type { ComponentProps } from 'react'
7 |
8 | import { Button } from '@/components/Button'
9 |
10 | import { Tooltip } from '.'
11 |
12 | type TooltipProps = ComponentProps
13 |
14 | const meta = {
15 | args: {
16 | align: undefined,
17 | children: 'Hover me',
18 | content: 'This is a tooltip',
19 | disabled: false,
20 | side: undefined,
21 | withArrow: true,
22 | wrapInButton: false,
23 | },
24 | argTypes: {
25 | content: { control: 'text' },
26 | trigger: {
27 | control: 'radio',
28 | mapping: {
29 | Button: ,
30 | 'Icon Button': (
31 | }
33 | iconOnly
34 | label="Hover me"
35 | variant="text"
36 | />
37 | ),
38 | Text: 'Hover me',
39 | },
40 | options: ['Text', 'Button', 'Icon Button'],
41 | },
42 | },
43 | component: Tooltip,
44 | parameters: {
45 | docs: {
46 | subtitle: `🎩 A tip of the hat from Dr. Facilier. - Dr. Facilier - The Princess and the Frog`,
47 | },
48 | },
49 |
50 | title: 'Molecules/Tooltip',
51 | } satisfies Meta
52 |
53 | export default meta
54 | type Story = StoryObj
55 |
56 | export const Playground: Story = {
57 | args: {
58 | onDisplayChange: fn(),
59 | onHide: fn(),
60 | onInteractOutside: fn(),
61 | onShow: fn(),
62 | },
63 | }
64 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Tooltip/index.ts:
--------------------------------------------------------------------------------
1 | export { default as Tooltip } from './Tooltip.js'
2 | export type { TooltipProps } from './Tooltip.types.js'
3 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Typography/Typography.constants.ts:
--------------------------------------------------------------------------------
1 | import type { ElementType } from 'react'
2 |
3 | export const GROUP_NAME = 'typography'
4 |
5 | export enum Variants {
6 | Body1 = 'body-1',
7 | Body1Bold = 'body-1-bold',
8 | Body1Link = 'body-1-link',
9 | Body1Median = 'body-1-median',
10 |
11 | Body2 = 'body-2',
12 | Body2Bold = 'body-2-bold',
13 | Body2Link = 'body-2-link',
14 | Body2Median = 'body-2-median',
15 |
16 | CaptionBold = 'caption-bold',
17 | CaptionLink = 'caption-link',
18 | CaptionMedian = 'caption-median',
19 |
20 | Display1 = 'display-1',
21 | Display2 = 'display-2',
22 | DisplayWide = 'display-wide',
23 |
24 | Heading1 = 'heading-1',
25 | Heading2 = 'heading-2',
26 | Heading3 = 'heading-3',
27 | Heading3Link = 'heading-3-link',
28 | Heading4 = 'heading-4',
29 | Heading4Link = 'heading-4-link',
30 | }
31 |
32 | export const DEFAULT_VARIANT = Variants.Body1
33 |
34 | export const VARIANTS_MAPPING: Record = {
35 | [Variants.Body1]: 'p',
36 | [Variants.Body1Bold]: 'p',
37 | [Variants.Body1Link]: 'a',
38 | [Variants.Body1Median]: 'p',
39 |
40 | [Variants.Body2]: 'p',
41 | [Variants.Body2Bold]: 'p',
42 | [Variants.Body2Link]: 'a',
43 | [Variants.Body2Median]: 'p',
44 |
45 | [Variants.CaptionBold]: 'p',
46 | [Variants.CaptionLink]: 'a',
47 | [Variants.CaptionMedian]: 'p',
48 |
49 | [Variants.Display1]: 'h1',
50 | [Variants.Display2]: 'h2',
51 | [Variants.DisplayWide]: 'h3',
52 |
53 | [Variants.Heading1]: 'h1',
54 | [Variants.Heading2]: 'h2',
55 | [Variants.Heading3]: 'h3',
56 | [Variants.Heading3Link]: 'a',
57 | [Variants.Heading4]: 'h4',
58 | [Variants.Heading4Link]: 'a',
59 | }
60 |
61 | export const DEFAULT_ELEMENT: ElementType = 'p'
62 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Typography/Typography.mdx:
--------------------------------------------------------------------------------
1 | import {
2 | ArgTypes,
3 | Controls,
4 | Description,
5 | Meta,
6 | Primary,
7 | Stories,
8 | Subtitle,
9 | Title,
10 | } from '@storybook/blocks'
11 |
12 | import * as TypographyStories from './Typography.stories'
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | ---
23 |
24 | ## Props
25 |
26 | On top of all the props, attributes and event handler you can set on a
27 | `` element (by default, or any other `element` you may choose for your
28 | typography), the component accepts the following props:
29 |
30 |
31 |
32 |
33 |
34 | ## Playground
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Typography/Typography.types.ts:
--------------------------------------------------------------------------------
1 | import type { AllHTMLAttributes, ElementType, ReactNode } from 'react'
2 |
3 | import { Variants } from './Typography.constants'
4 |
5 | export interface TypographyProps extends AllHTMLAttributes {
6 | /** The text to display. */
7 | children?: ReactNode
8 | /** The HTML element to use to display your text. */
9 | element?: ElementType
10 | /**
11 | * Indicates to inline all styles (including resets, font, ...) or only the
12 | * needed ones.
13 | *
14 | * Only used with `inlineStyle` enabled.
15 | */
16 | fullStyle?: boolean
17 | /**
18 | * Indicates to inline the styles instead of using any CSS classes.
19 | *
20 | * The typical usage for this is when creating HTML for an email.
21 | */
22 | inlineStyle?: boolean
23 | /** The variant of typography (style and size) to use. */
24 | variant?: `${Variants}`
25 | /**
26 | * Force the XS variation of typography.
27 | * In particular of headings.s
28 | *
29 | * This is useful when inlining styles.
30 | */
31 | xs?: boolean
32 |
33 | /**
34 | * Disable Sendgrid click tracking.
35 | * This will output a `clicktracking="off"` attribute to the `a` element.
36 | *
37 | * Of course this is only useful for a Typography component that outputs an
38 | * `a` element with an `href` attribute (i.e. a link).
39 | */
40 | disableClickTracking?: boolean
41 | }
42 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/Typography/index.ts:
--------------------------------------------------------------------------------
1 | export {
2 | DEFAULT_ELEMENT as DEFAULT_TYPOGRAPHY_ELEMENT,
3 | DEFAULT_VARIANT as DEFAULT_TYPOGRAPHY_VARIANT,
4 | Variants as TypographyVariants,
5 | VARIANTS_MAPPING as typographyVariantToElement,
6 | } from './Typography.constants.js'
7 | export { default as Typography } from './Typography.js'
8 | export type { TypographyProps } from './Typography.types.js'
9 |
--------------------------------------------------------------------------------
/packages/fractal/src/components/index.ts:
--------------------------------------------------------------------------------
1 | export * from './Autocomplete/index.js'
2 | export * from './Avatar/index.js'
3 | export * from './Badge/index.js'
4 | export * from './Button/index.js'
5 | export * from './Card/index.js'
6 | export * from './Confirm/index.js'
7 | export * from './CuteIcon/index.js'
8 | export * from './DateTimePicker/index.js'
9 | export * from './Dialog/index.js'
10 | export * from './Dropdown/index.js'
11 | export * from './EmojiPicker/index.js'
12 | export * from './Header/index.js'
13 | export * from './InputCheckbox/index.js'
14 | export * from './InputDate/index.js'
15 | export * from './InputFile/index.js'
16 | export * from './InputPhone/index.js'
17 | export * from './InputPinCode/index.js'
18 | export * from './InputRadio/index.js'
19 | export * from './InputText/index.js'
20 | export * from './Loader/index.js'
21 | export * from './Logo/index.js'
22 | export * from './Menu/index.js'
23 | export * from './Paper/index.js'
24 | export * from './Popover/index.js'
25 | export * from './Progress/index.js'
26 | export * from './ScrollArea/index.js'
27 | export * from './Select/index.js'
28 | export * from './Skeleton/index.js'
29 | export * from './Slider/index.js'
30 | export * from './Stepper/index.js'
31 | export * from './Switch/index.js'
32 | export * from './Tabs/index.js'
33 | export * from './Tag/index.js'
34 | export * from './Textarea/index.js'
35 | export * from './Toggle/index.js'
36 | export * from './ToggleGroup/index.js'
37 | export * from './Toolbar/index.js'
38 | export * from './Tooltip/index.js'
39 | export * from './Typography/index.js'
40 |
--------------------------------------------------------------------------------
/packages/fractal/src/hooks/index.ts:
--------------------------------------------------------------------------------
1 | export { default as useTheme } from './useTheme.js'
2 |
--------------------------------------------------------------------------------
/packages/fractal/src/hooks/useTheme.ts:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { useContext } from 'react'
4 |
5 | import isEmpty from 'lodash/fp/isEmpty'
6 |
7 | import { DEFAULT_THEME, Themes } from '@/constants'
8 | import { ThemeContext } from '@/ThemeProvider'
9 |
10 | export default function useTheme(
11 | themeOverride?: Themes,
12 | { fail = false, log = false } = {},
13 | ) {
14 | if (!isEmpty(themeOverride)) {
15 | return themeOverride
16 | }
17 |
18 | // Try to load the context.
19 | try {
20 | // eslint-disable-next-line react-hooks/rules-of-hooks
21 | const themeContext = useContext(ThemeContext)
22 |
23 | return themeContext.theme
24 | } catch (error) {
25 | if (log) {
26 | console.warn(
27 | '[FRACTAL][THEME] Unable to load the global theme as no ThemeProvider has been found!',
28 | )
29 | }
30 |
31 | if (fail) {
32 | throw error
33 | }
34 | }
35 |
36 | return DEFAULT_THEME
37 | }
38 |
--------------------------------------------------------------------------------
/packages/fractal/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './components/index.js'
2 | export * from './constants.js'
3 | export * from './hooks/index.js'
4 | export * from './styles/helpers.js'
5 | export * from './ThemeProvider.js'
6 | export * from './types.js'
7 |
--------------------------------------------------------------------------------
/packages/fractal/src/styles/global.css:
--------------------------------------------------------------------------------
1 | @import url('normalize.css') layer(reset);
2 | @import url('tailwindcss/base') layer(base);
3 | @import url('./polyfills.css') layer(base);
4 | @import url('@snowball-tech/design-tokens/dist/web/css/fonts.css')
5 | layer(fractal);
6 | @import url('@snowball-tech/design-tokens/dist/web/css/variables.css')
7 | layer(fractal);
8 | @import url('tailwindcss/components');
9 | @import url('tailwindcss/utilities');
10 |
11 | @layer reset, base, fractal, tokens, recipes, utilities;
12 |
13 | :root {
14 | --tw-translate-x: 0;
15 | --tw-translate-y: 0;
16 | --tw-rotate: 0;
17 | --tw-skew-x: 0;
18 | --tw-skew-y: 0;
19 | --tw-scale-x: 1;
20 | --tw-scale-y: 1;
21 | }
22 |
23 | @layer reset {
24 | *,
25 | ::before,
26 | ::after {
27 | border-width: 0;
28 | border-style: solid;
29 | border-color: var(--color-border-default);
30 | }
31 |
32 | html,
33 | body {
34 | margin: 0;
35 | padding: 0;
36 | }
37 |
38 | h1,
39 | h2,
40 | h3,
41 | h4,
42 | h5,
43 | h6,
44 | p,
45 | ol,
46 | ul {
47 | margin: 0;
48 | }
49 |
50 | div {
51 | box-sizing: border-box;
52 | }
53 |
54 | a {
55 | color: var(--color-brand-secondary);
56 | }
57 |
58 | * {
59 | -webkit-tap-highlight-color: transparent;
60 | }
61 |
62 | *::selection {
63 | background-color: var(--color-brand-primary);
64 | }
65 |
66 | *:focus-visible {
67 | outline: none;
68 | }
69 | }
70 |
71 | @layer utilities {
72 | @supports (height: 100dvh) {
73 | .h-screen {
74 | height: 100dvh;
75 | }
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/packages/fractal/src/tests_helpers.ts:
--------------------------------------------------------------------------------
1 | import { userEvent } from '@storybook/test'
2 |
3 | import { sleep } from './utils'
4 |
5 | export async function slowType(
6 | text: string,
7 | target: HTMLElement,
8 | { strokeDelay = 50 } = {},
9 | ) {
10 | await userEvent.click(target)
11 | await sleep(100)
12 |
13 | for (let index = 0; index < text.length; index += 1) {
14 | // eslint-disable-next-line no-await-in-loop
15 | await userEvent.type(target, text[index]!, { skipClick: true })
16 | // eslint-disable-next-line no-await-in-loop
17 | await sleep(strokeDelay)
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/packages/fractal/src/types.ts:
--------------------------------------------------------------------------------
1 | import { breakpoints } from '@snowball-tech/design-tokens/dist/web/typescript/constants'
2 |
3 | export type Breakpoint = keyof typeof breakpoints
4 |
--------------------------------------------------------------------------------
/packages/fractal/stories/Tokens.mdx:
--------------------------------------------------------------------------------
1 | import { Meta } from '@storybook/blocks'
2 |
3 |
4 |
5 | # Tokens
6 |
7 | ---
8 |
9 | All design values _(colors, breakpoints, shadows, spacings, ...)_ are defined as
10 | design tokens.
11 |
12 | You can find those tokens in the
13 | [`design-tokens` directory of the Fractal repository](https://github.com/snowball-tech/fractal/tree/main/packages/design-tokens)
14 |
15 | > ##### ℹ️ Info
16 | >
17 | > ---
18 | >
19 | > For more information about design tokens, read the
20 | > [README](https://github.com/snowball-tech/fractal/blob/main/packages/design-tokens/README.md)
21 |
22 | For convenience and ease of use, those tokens are translated into usable
23 | resources when developing your application.
24 |
25 | ## CSS variables
26 |
27 | All tokens are exported as CSS variables in the
28 | `@snowball-tech/design-tokens/dist/web/css/variables.css` file
29 | _(exported by the
30 | [`@snowball-tech/design-tokens`](https://www.npmjs.com/package/@snowball-tech/design-tokens)
31 | package)_.
32 |
33 | The variables are named exactly like the corresponding tokens, except that the
34 | "." is replaced by a "-" _(and of course, variables are prefixed with "--")_.
35 |
36 | ## JavaScript/TypeScript constants
37 |
38 | If you need to use a token in your JavaScript/TypeScript code, you can import
39 | any values from the
40 | `@snowball-tech/design-tokens/dist/web/typescript/design-tokens.js` file
41 | _(exported by the
42 | [`@snowball-tech/design-tokens`](https://www.npmjs.com/package/@snowball-tech/design-tokens)
43 | package)_.
44 |
45 | The constants are named exactly like the corresponding tokens but in
46 | [PascalCase](https://techterms.com/definition/pascalcase)
47 |
--------------------------------------------------------------------------------
/packages/fractal/tailwind.config.ts:
--------------------------------------------------------------------------------
1 | // eslint-disable-next-line no-restricted-exports
2 | export { default } from '@snowball-tech/design-tokens/dist/web/tailwindcss/tailwind.config'
3 |
--------------------------------------------------------------------------------
/packages/fractal/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "noEmit": false
5 | },
6 | "include": ["src/**/*.ts", "src/**/*.tsx"],
7 | "files": ["global.d.ts", "index.ts"],
8 | "exclude": ["src/**/*.stories.*", "src/**/*.mdx"],
9 | "references": []
10 | }
11 |
--------------------------------------------------------------------------------
/packages/fractal/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "baseUrl": ".",
5 | "isolatedModules": true,
6 | "lib": ["DOM", "DOM.Iterable", "ESNext"],
7 | "module": "ESNext",
8 | "moduleResolution": "bundler",
9 | "outDir": "./dist",
10 | "paths": {
11 | "@/*": ["./src/*"]
12 | },
13 | "rootDir": "./",
14 | "target": "ESNext",
15 | "useDefineForClassFields": true
16 | },
17 | "include": [
18 | "./*.ts",
19 | "src/**/*.ts",
20 | "src/**/*.tsx",
21 | "./.storybook/*.ts",
22 | "./.storybook/*.tsx",
23 | "./.storybook/*.mdx",
24 | "./stories"
25 | ],
26 | "files": ["global.d.ts"],
27 | "references": []
28 | }
29 |
--------------------------------------------------------------------------------
/renovate.json5:
--------------------------------------------------------------------------------
1 | {
2 | $schema: 'https://docs.renovatebot.com/renovate-schema.json',
3 |
4 | // https://docs.renovatebot.com/configuration-options/#extends
5 | extends: [
6 | 'github>snowball-tech/glacier//packages/renovate-config/default.json5',
7 | ],
8 |
9 | enabled: false,
10 | }
11 |
--------------------------------------------------------------------------------
/scripts/check-tokens.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | cd "$(dirname "$0")/../packages/fractal" >/dev/null 2>&1 || exit 1
4 |
5 | tokens=$(grep -RPoh "var\(--[^ ,\"=$]+\)" --exclude-dir={node_modules,dist,storybook-static} .storybook src stories | sort | sed -e "s/var(//g" | sed -e "s/)//g")
6 |
7 | for token in $tokens; do
8 | count=$(grep -c -- "$token" "../../node_modules/@snowball-tech/design-tokens/dist/web/css/variables.css")
9 | if [ "$count" -eq 0 ]; then
10 | echo "Token '$token' is not defined in the design tokens."
11 | fi
12 | done
13 |
14 | cd - >/dev/null 2>&1 || exit 2
15 |
--------------------------------------------------------------------------------
/scripts/copy-storybook.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # shellcheck disable=SC2181
4 |
5 | # shellcheck disable=SC1090
6 | source "$(dirname "$0")/colors.sh"
7 |
8 | from="$1"
9 | to="$2"
10 |
11 | if [ -z "$from" ] || [ -z "$to" ]; then
12 | echo "Usage: $0 "
13 | exit 1
14 | fi
15 |
16 | echo -n "$(bold_info "Copying '$from' to '$to'... ")"
17 |
18 | copy=$(cp -r "$from" "$to" 2>&1)
19 | if [ $? -gt 0 ]; then
20 | bold_error "FAILED"
21 | error "$copy"
22 |
23 | warning "Something wrong happened during the copy of '$from' to '$to'."
24 |
25 | exit 0
26 | fi
27 |
28 | bold_success "DONE"
29 |
30 | bold_success "Storybook successfully copied!"
31 | echo ""
32 |
33 | info "$to"
34 |
35 | echo -n "$BLUE"
36 | ls "$to"
37 | echo -n "$NORMAL"
38 |
--------------------------------------------------------------------------------
/scripts/filter-vercel-deployments.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/bash
2 |
3 | echo "Checking if Vercel deployment should be skipped..."
4 |
5 | # If VERCEL_GIT_COMMIT_REF env var starts with "renovate/", then exit with 0 to
6 | # block the Vercel deployment.
7 |
8 | if [[ "${VERCEL_GIT_COMMIT_REF}" == "renovate"/* ]]; then
9 | echo "Renovate branch detected! Skipping deployment!"
10 | exit 0
11 | fi
12 |
13 | # If the commit message contains "[skip ci]" (e.g. release commit generated by
14 | # semantic release), then exit with 0 to block the Vercel deployment.
15 |
16 | if [[ "${VERCEL_GIT_COMMIT_MESSAGE}" == *"[skip ci]"* ]]; then
17 | echo "Commit message contains \"[skip ci]\"! Skipping deployment!"
18 | exit 0
19 | fi
20 |
21 | # Otherwise exit with 1 to carry on with the deployment.
22 |
23 | echo "Continuing with deployment!"
24 |
25 | exit 1
26 |
--------------------------------------------------------------------------------
/scripts/setup-freezer.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # shellcheck disable=SC2181
4 |
5 | # Setup SSH keys to access GitHub repositories.
6 |
7 | # shellcheck disable=SC1090
8 | source "$(dirname "$0")/colors.sh"
9 |
10 | if [ -z "$FREEZER_TOKEN" ]; then
11 | bold_error "You must defined the 'FREEZER_TOKEN' environment variable to use this script!"
12 | exit 1
13 | fi
14 |
15 | if [ -n "$CI" ]; then
16 | echo -n "$(info "Updating Git config to enforce HTTPS to connect to Freezer... ")"
17 | git config --global url."https://${FREEZER_TOKEN}@github.com/snowball-tech/freezer.git".insteadOf "git@github.com:snowball-tech/freezer.git"
18 | bold_success "DONE"
19 | else
20 | bold_info "Nothing to do, not in CI environment..."
21 | fi
22 |
--------------------------------------------------------------------------------
/tsconfig.eslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "noEmit": true,
5 | "allowJs": true
6 | },
7 | "include": ["**/*.ts", "**/*.d.ts", "**/*.tsx", "**/*.js", "**/*.jsx"],
8 | "files": []
9 | }
10 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "allowJs": true,
4 | "checkJs": false,
5 | "composite": false,
6 | "declaration": true,
7 | "declarationMap": true,
8 | "esModuleInterop": true,
9 | "exactOptionalPropertyTypes": false,
10 | "forceConsistentCasingInFileNames": true,
11 | "incremental": false,
12 | "jsx": "react-jsx",
13 | "module": "NodeNext",
14 | "moduleResolution": "nodenext",
15 | "noEmit": false,
16 | "noErrorTruncation": true,
17 | "noImplicitOverride": true,
18 | "noImplicitReturns": true,
19 | "noUnusedLocals": true,
20 | "noUnusedParameters": true,
21 | "noUncheckedIndexedAccess": true,
22 | "preserveSymlinks": true,
23 | "preserveWatchOutput": true,
24 | "resolveJsonModule": true,
25 | "removeComments": true,
26 | "skipLibCheck": true,
27 | "sourceMap": true,
28 | "strict": true,
29 | "target": "ES6",
30 | "useDefineForClassFields": true
31 | },
32 | "include": [],
33 | "exclude": [
34 | "**/.yarn/plugins/**/*",
35 | "**/.yarn/releases/**/*",
36 | "**/build",
37 | "**/dist",
38 | "**/out",
39 | "**/node_modules"
40 | ],
41 | "files": [],
42 | "references": [
43 | {
44 | "path": "packages/design-tokens"
45 | },
46 | {
47 | "path": "packages/fractal"
48 | }
49 | ]
50 | }
51 |
--------------------------------------------------------------------------------
/yarn.config.cjs:
--------------------------------------------------------------------------------
1 | // @ts-check
2 |
3 | /** @type {import('@yarnpkg/types')} */
4 | const { defineConfig } = require(`@yarnpkg/types`)
5 |
6 | /**
7 | * This rule will enforce that a workspace MUST depend on the same version of
8 | * a dependency as the one used by the other workspaces.
9 | *
10 | * @param {Context} context
11 | */
12 | function enforceConsistentDependenciesAcrossTheProject({ Yarn }) {
13 | for (const dependency of Yarn.dependencies()) {
14 | if (dependency.type === `peerDependencies`) continue
15 |
16 | for (const otherDependency of Yarn.dependencies({
17 | ident: dependency.ident,
18 | })) {
19 | if (otherDependency.type === `peerDependencies`) continue
20 |
21 | dependency.update(otherDependency.range)
22 | }
23 | }
24 | }
25 |
26 | module.exports = defineConfig({
27 | constraints: async (context) => {
28 | enforceConsistentDependenciesAcrossTheProject(context)
29 | },
30 | })
31 |
--------------------------------------------------------------------------------