@felloinnovations/brand-kit 0.4.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +198 -24
- package/CHANGELOG.md +221 -0
- package/README.md +38 -9
- package/design-system/01-how-claude-decides.md +26 -17
- package/design-system/02-principles.md +11 -6
- package/design-system/03-colour.md +135 -47
- package/design-system/04-type.md +45 -23
- package/design-system/05-space-and-layout.md +175 -52
- package/design-system/06-sizing-profiles.md +4 -4
- package/design-system/07-scrolling.md +66 -20
- package/design-system/08-choosing-components.md +50 -22
- package/design-system/09-charts.md +71 -28
- package/design-system/10-patterns.md +33 -10
- package/design-system/11-page-recipes.md +110 -23
- package/design-system/12-content.md +2 -1
- package/design-system/13-motion.md +330 -47
- package/design-system/14-accessibility.md +47 -24
- package/design-system/15-ai-experiences.md +11 -6
- package/design-system/16-creativity.md +1 -1
- package/design-system/17-decisions.md +367 -1
- package/design-system/18-checklist.md +79 -16
- package/design-system/19-public-pages.md +6 -4
- package/design-system/20-palettes.md +275 -0
- package/design-system/README.md +30 -17
- package/design-system/components/ActionList/README.md +96 -10
- package/design-system/components/ActionList/preview.html +52 -7
- package/design-system/components/ActionList/style.css +64 -0
- package/design-system/components/ActivityGrid/README.md +38 -2
- package/design-system/components/ActivityGrid/preview.html +1 -1
- package/design-system/components/ActivityGrid/style.css +35 -0
- package/design-system/components/AppShell/README.md +205 -75
- package/design-system/components/AppShell/preview.html +339 -58
- package/design-system/components/AppShell/style.css +154 -0
- package/design-system/components/Avatar/README.md +37 -10
- package/design-system/components/Avatar/preview.html +13 -4
- package/design-system/components/Avatar/style.css +14 -0
- package/design-system/components/Badge/README.md +41 -19
- package/design-system/components/Badge/preview.html +13 -10
- package/design-system/components/Badge/style.css +23 -0
- package/design-system/components/Banner/README.md +30 -9
- package/design-system/components/Banner/preview.html +1 -1
- package/design-system/components/Banner/style.css +19 -0
- package/design-system/components/Breadcrumb/README.md +58 -46
- package/design-system/components/Breadcrumb/preview.html +16 -16
- package/design-system/components/Breadcrumb/style.css +17 -0
- package/design-system/components/Button/README.md +113 -55
- package/design-system/components/Button/preview.html +98 -25
- package/design-system/components/Button/style.css +86 -0
- package/design-system/components/Card/README.md +158 -49
- package/design-system/components/Card/preview.html +141 -19
- package/design-system/components/Card/style.css +115 -0
- package/design-system/components/CardBoard/README.md +58 -37
- package/design-system/components/CardBoard/preview.html +26 -29
- package/design-system/components/ChatCard/README.md +115 -29
- package/design-system/components/ChatCard/preview.html +149 -32
- package/design-system/components/ChatCard/style.css +49 -0
- package/design-system/components/ChatShell/README.md +116 -0
- package/design-system/components/ChatShell/preview.html +201 -0
- package/design-system/components/ChatShell/style.css +86 -0
- package/design-system/components/ChatTurn/README.md +78 -35
- package/design-system/components/ChatTurn/preview.html +60 -28
- package/design-system/components/ChatTurn/style.css +50 -0
- package/design-system/components/CheckRow/README.md +141 -0
- package/design-system/components/CheckRow/preview.html +140 -0
- package/design-system/components/CheckRow/style.css +88 -0
- package/design-system/components/Checkbox/README.md +58 -22
- package/design-system/components/Checkbox/preview.html +112 -50
- package/design-system/components/Checkbox/style.css +45 -0
- package/design-system/components/Chip/README.md +78 -47
- package/design-system/components/Chip/preview.html +29 -4
- package/design-system/components/Chip/style.css +17 -0
- package/design-system/components/Combobox/README.md +44 -11
- package/design-system/components/Combobox/preview.html +35 -12
- package/design-system/components/Combobox/style.css +54 -0
- package/design-system/components/Composer/README.md +137 -35
- package/design-system/components/Composer/preview.html +115 -40
- package/design-system/components/Composer/style.css +81 -0
- package/design-system/components/ConfirmDialog/README.md +73 -52
- package/design-system/components/ConfirmDialog/preview.html +70 -26
- package/design-system/components/ConfirmDialog/style.css +5 -0
- package/design-system/components/Cover/preview.html +3 -3
- package/design-system/components/Cover/style.css +19 -0
- package/design-system/components/DateInput/README.md +77 -12
- package/design-system/components/DateInput/preview.html +27 -12
- package/design-system/components/DateInput/style.css +38 -0
- package/design-system/components/Dialog/README.md +112 -44
- package/design-system/components/Dialog/preview.html +141 -18
- package/design-system/components/Dialog/style.css +74 -0
- package/design-system/components/EmptyState/README.md +42 -12
- package/design-system/components/EmptyState/preview.html +11 -11
- package/design-system/components/EmptyState/style.css +9 -0
- package/design-system/components/EntryShell/README.md +73 -48
- package/design-system/components/EntryShell/preview.html +60 -27
- package/design-system/components/EntryShell/style.css +19 -0
- package/design-system/components/FeatureGrid/README.md +61 -39
- package/design-system/components/FeatureGrid/preview.html +2 -2
- package/design-system/components/FeatureGrid/style.css +20 -0
- package/design-system/components/FileUpload/README.md +33 -3
- package/design-system/components/FileUpload/preview.html +18 -4
- package/design-system/components/FileUpload/style.css +23 -0
- package/design-system/components/FilterBar/README.md +114 -0
- package/design-system/components/FilterBar/preview.html +82 -0
- package/design-system/components/FilterBar/style.css +22 -0
- package/design-system/components/Fold/README.md +84 -26
- package/design-system/components/Fold/preview.html +77 -34
- package/design-system/components/Fold/style.css +48 -0
- package/design-system/components/Footer/README.md +62 -39
- package/design-system/components/Footer/preview.html +5 -5
- package/design-system/components/Footer/style.css +30 -0
- package/design-system/components/FunnelBars/README.md +24 -3
- package/design-system/components/FunnelBars/preview.html +5 -5
- package/design-system/components/FunnelBars/style.css +13 -0
- package/design-system/components/GoalBars/README.md +54 -10
- package/design-system/components/GoalBars/preview.html +69 -28
- package/design-system/components/GoalBars/style.css +51 -0
- package/design-system/components/GoalTicks/README.md +74 -58
- package/design-system/components/GoalTicks/preview.html +41 -118
- package/design-system/components/GoalTicks/style.css +37 -0
- package/design-system/components/GoalTubes/README.md +29 -3
- package/design-system/components/GoalTubes/preview.html +6 -6
- package/design-system/components/GoalTubes/style.css +23 -0
- package/design-system/components/Heatmap/README.md +133 -0
- package/design-system/components/Heatmap/preview.html +168 -0
- package/design-system/components/Heatmap/style.css +119 -0
- package/design-system/components/Hero/README.md +58 -40
- package/design-system/components/Hero/preview.html +1 -1
- package/design-system/components/Hero/style.css +19 -0
- package/design-system/components/HoverCard/README.md +114 -0
- package/design-system/components/HoverCard/preview.html +107 -0
- package/design-system/components/HoverCard/style.css +59 -0
- package/design-system/components/IconButton/README.md +69 -38
- package/design-system/components/IconButton/preview.html +77 -43
- package/design-system/components/IconButton/style.css +45 -0
- package/design-system/components/Input/README.md +36 -11
- package/design-system/components/Input/preview.html +1 -1
- package/design-system/components/Input/style.css +23 -0
- package/design-system/components/KanbanBoard/README.md +93 -45
- package/design-system/components/KanbanBoard/preview.html +159 -43
- package/design-system/components/KanbanBoard/style.css +53 -0
- package/design-system/components/Kbd/README.md +25 -9
- package/design-system/components/Kbd/preview.html +6 -2
- package/design-system/components/Kbd/style.css +9 -0
- package/design-system/components/KitButton/README.md +81 -47
- package/design-system/components/KitButton/preview.html +35 -13
- package/design-system/components/KitButton/style.css +46 -0
- package/design-system/components/KitCard/README.md +75 -44
- package/design-system/components/KitCard/preview.html +18 -10
- package/design-system/components/KitCard/style.css +15 -0
- package/design-system/components/KitInput/README.md +54 -39
- package/design-system/components/KitInput/preview.html +7 -7
- package/design-system/components/KitInput/style.css +23 -0
- package/design-system/components/Leaderboard/README.md +76 -49
- package/design-system/components/Leaderboard/preview.html +61 -26
- package/design-system/components/Leaderboard/style.css +44 -0
- package/design-system/components/ListDetail/README.md +222 -0
- package/design-system/components/ListDetail/preview.html +213 -0
- package/design-system/components/ListDetail/style.css +148 -0
- package/design-system/components/LoadBar/README.md +79 -0
- package/design-system/components/LoadBar/preview.html +40 -0
- package/design-system/components/LoadBar/style.css +17 -0
- package/design-system/components/MarketingNav/README.md +76 -42
- package/design-system/components/MarketingNav/preview.html +37 -8
- package/design-system/components/MarketingNav/style.css +45 -0
- package/design-system/components/Matrix/README.md +129 -0
- package/design-system/components/Matrix/preview.html +99 -0
- package/design-system/components/Matrix/style.css +84 -0
- package/design-system/components/Menu/README.md +117 -41
- package/design-system/components/Menu/preview.html +85 -23
- package/design-system/components/Menu/style.css +61 -0
- package/design-system/components/Meter/README.md +39 -4
- package/design-system/components/Meter/preview.html +18 -1
- package/design-system/components/Meter/style.css +23 -0
- package/design-system/components/MetricTile/README.md +237 -0
- package/design-system/components/MetricTile/preview.html +241 -0
- package/design-system/components/MetricTile/style.css +129 -0
- package/design-system/components/Morph/README.md +106 -0
- package/design-system/components/Morph/preview.html +103 -0
- package/design-system/components/Morph/style.css +31 -0
- package/design-system/components/Motion/README.md +164 -0
- package/design-system/components/Motion/preview.html +2537 -0
- package/design-system/components/NumberInput/README.md +27 -8
- package/design-system/components/NumberInput/preview.html +21 -5
- package/design-system/components/NumberInput/style.css +34 -0
- package/design-system/components/PaceBar/README.md +75 -0
- package/design-system/components/PaceBar/preview.html +67 -0
- package/design-system/components/PaceBar/style.css +25 -0
- package/design-system/components/Page/README.md +57 -18
- package/design-system/components/Page/preview.html +15 -17
- package/design-system/components/Page/style.css +7 -0
- package/design-system/components/PageBar/README.md +90 -34
- package/design-system/components/PageBar/preview.html +60 -19
- package/design-system/components/PageBar/style.css +35 -0
- package/design-system/components/PageHero/README.md +87 -51
- package/design-system/components/PageHero/preview.html +35 -6
- package/design-system/components/PageHero/style.css +31 -0
- package/design-system/components/Pagination/README.md +70 -49
- package/design-system/components/Pagination/preview.html +24 -15
- package/design-system/components/Pagination/style.css +12 -0
- package/design-system/components/Panel/README.md +109 -51
- package/design-system/components/Panel/preview.html +118 -20
- package/design-system/components/Panel/style.css +51 -0
- package/design-system/components/PasswordInput/README.md +50 -18
- package/design-system/components/PasswordInput/preview.html +71 -21
- package/design-system/components/PasswordInput/style.css +31 -0
- package/design-system/components/Plate/README.md +75 -17
- package/design-system/components/Plate/preview.html +40 -7
- package/design-system/components/Plate/style.css +37 -0
- package/design-system/components/Popover/README.md +70 -49
- package/design-system/components/Popover/preview.html +44 -22
- package/design-system/components/Popover/style.css +41 -0
- package/design-system/components/PricingTable/README.md +69 -49
- package/design-system/components/PricingTable/preview.html +21 -21
- package/design-system/components/PricingTable/style.css +21 -0
- package/design-system/components/ProgressPetals/README.md +31 -3
- package/design-system/components/ProgressPetals/preview.html +14 -15
- package/design-system/components/ProgressPetals/style.css +27 -0
- package/design-system/components/README.md +151 -0
- package/design-system/components/Radio/README.md +40 -17
- package/design-system/components/Radio/preview.html +16 -1
- package/design-system/components/Radio/style.css +21 -0
- package/design-system/components/RankBar/README.md +29 -2
- package/design-system/components/RankBar/preview.html +14 -12
- package/design-system/components/RankBar/style.css +18 -0
- package/design-system/components/Ring/README.md +61 -11
- package/design-system/components/Ring/preview.html +55 -10
- package/design-system/components/Ring/style.css +49 -0
- package/design-system/components/ScoreHero/README.md +91 -0
- package/design-system/components/ScoreHero/preview.html +104 -0
- package/design-system/components/ScoreHero/style.css +32 -0
- package/design-system/components/Section/README.md +72 -33
- package/design-system/components/Section/preview.html +46 -16
- package/design-system/components/Section/style.css +18 -0
- package/design-system/components/Segmented/README.md +100 -55
- package/design-system/components/Segmented/preview.html +107 -26
- package/design-system/components/Segmented/style.css +94 -0
- package/design-system/components/SegmentedProgress/README.md +64 -0
- package/design-system/components/SegmentedProgress/preview.html +69 -0
- package/design-system/components/SegmentedProgress/style.css +11 -0
- package/design-system/components/Select/README.md +47 -12
- package/design-system/components/Select/preview.html +28 -2
- package/design-system/components/Select/style.css +22 -0
- package/design-system/components/ShareBar/README.md +69 -0
- package/design-system/components/ShareBar/preview.html +72 -0
- package/design-system/components/ShareBar/style.css +25 -0
- package/design-system/components/SideList/README.md +147 -0
- package/design-system/components/SideList/preview.html +139 -0
- package/design-system/components/SideList/style.css +94 -0
- package/design-system/components/Skeleton/README.md +53 -16
- package/design-system/components/Skeleton/preview.html +35 -23
- package/design-system/components/Skeleton/style.css +17 -0
- package/design-system/components/Slider/README.md +95 -0
- package/design-system/components/Slider/preview.html +49 -0
- package/design-system/components/Slider/style.css +13 -0
- package/design-system/components/Split/README.md +112 -0
- package/design-system/components/Split/preview.html +105 -0
- package/design-system/components/Split/style.css +30 -0
- package/design-system/components/Starter/README.md +21 -9
- package/design-system/components/Starter/preview.html +5 -5
- package/design-system/components/Stat/README.md +64 -43
- package/design-system/components/Stat/preview.html +3 -3
- package/design-system/components/Stat/style.css +15 -0
- package/design-system/components/StatTiles/README.md +88 -44
- package/design-system/components/StatTiles/preview.html +142 -71
- package/design-system/components/StatTiles/style.css +64 -0
- package/design-system/components/StatusLine/README.md +85 -0
- package/design-system/components/StatusLine/preview.html +49 -0
- package/design-system/components/StatusLine/style.css +14 -0
- package/design-system/components/StatusScreen/README.md +49 -35
- package/design-system/components/StatusScreen/preview.html +20 -5
- package/design-system/components/StatusScreen/style.css +9 -0
- package/design-system/components/StepLine/README.md +97 -0
- package/design-system/components/StepLine/preview.html +108 -0
- package/design-system/components/StepLine/style.css +62 -0
- package/design-system/components/Stepper/README.md +35 -13
- package/design-system/components/Stepper/style.css +13 -0
- package/design-system/components/StreakCalendar/README.md +22 -1
- package/design-system/components/StreakCalendar/preview.html +10 -10
- package/design-system/components/StreakCalendar/style.css +12 -0
- package/design-system/components/SuggestionChip/README.md +87 -0
- package/design-system/components/SuggestionChip/preview.html +42 -0
- package/design-system/components/SuggestionChip/style.css +20 -0
- package/design-system/components/Switch/README.md +44 -24
- package/design-system/components/Switch/preview.html +23 -8
- package/design-system/components/Switch/style.css +31 -0
- package/design-system/components/Table/README.md +129 -58
- package/design-system/components/Table/preview.html +106 -72
- package/design-system/components/Table/style.css +104 -0
- package/design-system/components/Tabs/README.md +71 -46
- package/design-system/components/Tabs/preview.html +56 -24
- package/design-system/components/Tabs/style.css +44 -0
- package/design-system/components/Testimonial/README.md +48 -32
- package/design-system/components/Testimonial/preview.html +14 -14
- package/design-system/components/Testimonial/style.css +12 -0
- package/design-system/components/TextArea/README.md +27 -11
- package/design-system/components/TextArea/preview.html +8 -2
- package/design-system/components/TextArea/style.css +12 -0
- package/design-system/components/ThemeSwitch/README.md +116 -0
- package/design-system/components/ThemeSwitch/preview.html +57 -0
- package/design-system/components/ThemeSwitch/style.css +6 -0
- package/design-system/components/TickRow/README.md +52 -36
- package/design-system/components/TickRow/preview.html +64 -41
- package/design-system/components/TickRow/style.css +23 -0
- package/design-system/components/TickStrip/README.md +95 -0
- package/design-system/components/TickStrip/preview.html +88 -0
- package/design-system/components/TickStrip/style.css +42 -0
- package/design-system/components/Tile/README.md +79 -18
- package/design-system/components/Tile/preview.html +91 -40
- package/design-system/components/Tile/style.css +36 -0
- package/design-system/components/Timeline/README.md +68 -48
- package/design-system/components/Timeline/preview.html +27 -15
- package/design-system/components/Timeline/style.css +25 -0
- package/design-system/components/Toast/README.md +70 -38
- package/design-system/components/Toast/preview.html +43 -8
- package/design-system/components/Toast/style.css +25 -0
- package/design-system/components/Tooltip/README.md +93 -35
- package/design-system/components/Tooltip/preview.html +69 -15
- package/design-system/components/Tooltip/style.css +78 -0
- package/design-system/components/TopBar/README.md +67 -53
- package/design-system/components/TopBar/preview.html +14 -27
- package/design-system/components/TopBar/style.css +35 -0
- package/design-system/components/TopicRail/README.md +108 -0
- package/design-system/components/TopicRail/preview.html +58 -0
- package/design-system/components/TopicRail/style.css +48 -0
- package/design-system/components/TrendBars/README.md +52 -14
- package/design-system/components/TrendBars/preview.html +65 -32
- package/design-system/components/TrendBars/style.css +25 -0
- package/design-system/components/TrendLine/README.md +164 -0
- package/design-system/components/TrendLine/preview.html +373 -0
- package/design-system/components/TrendLine/style.css +155 -0
- package/design-system/components/Well/README.md +64 -22
- package/design-system/components/Well/preview.html +14 -14
- package/design-system/components/Well/style.css +22 -0
- package/design-system/components/_house.css +324 -0
- package/design-system/components/bundle.css +4086 -744
- package/design-system/tokens.json +1310 -124
- package/dist/fello-core.css +2 -2
- package/dist/fello.css +6 -1369
- package/dist/fello.scoped.css +7 -0
- package/dist/index.d.ts +109 -10
- package/dist/index.js +781 -96
- package/dist/palettes.d.ts +464 -0
- package/dist/palettes.js +497 -0
- package/dist/scoped.d.ts +3 -0
- package/dist/scoped.js +16 -0
- package/dist/toast.d.ts +14 -0
- package/dist/toast.js +33 -29
- package/dist/tokens.d.ts +1686 -62
- package/dist/tokens.js +1668 -61
- package/package.json +20 -4
- package/scripts/check-palette.mjs +295 -0
- package/scripts/token-model.mjs +552 -0
- package/tokens/_dark.css +173 -0
- package/tokens/_palettes.css +46 -0
- package/tokens/_product.css +266 -53
- package/tokens/_source.hubl.css +39 -19
- package/tokens/design-tokens.json +319 -0
- package/tokens/palettes.ts +504 -0
- package/tokens/shadcn-compat.css +19 -19
- package/tokens/shadcn-compat.hsl.css +76 -0
- package/tokens/tokens.css +1287 -62
- package/tokens/tokens.md +587 -61
- package/tokens/tokens.root.css +1293 -62
- package/tokens/tokens.ts +1677 -64
|
@@ -1,94 +1,139 @@
|
|
|
1
|
-
Every switch and tab row on the platform:
|
|
2
|
-
|
|
1
|
+
Every switch and tab row on the platform: Seth's grey well with a navy current item, one component so the current
|
|
2
|
+
item always moves the same way.
|
|
3
3
|
|
|
4
4
|
## Use it when
|
|
5
5
|
|
|
6
6
|
- A view or a mode needs switching on one page (cold call, live transfer, follow-up; this week, this month, all time).
|
|
7
|
-
- A
|
|
8
|
-
- A
|
|
7
|
+
- A pane needs real tabs (`tabs`: a `role="tablist"` with arrow-key navigation), such as Seth's drawer tabs.
|
|
8
|
+
- A report's views carry a figure each (Seth's view tabs: "Your score 72"): `figures`.
|
|
9
|
+
- A page's period filter (`sm`, inside `FilterBar`) or a list head's filter (`clear`).
|
|
10
|
+
- A form's single choice among two to four short options (native radios inside the items).
|
|
9
11
|
|
|
10
12
|
## Not for
|
|
11
13
|
|
|
12
|
-
- A form's
|
|
13
|
-
-
|
|
14
|
+
- A form's choice among many, or long options: use `Radio`/`RadioGroup` or `Select`.
|
|
15
|
+
- Five or more sections of one page: use `Tabs`.
|
|
16
|
+
- An act that does something once: use `Button`.
|
|
14
17
|
- A removable or markable fact: use `Chip`.
|
|
15
18
|
|
|
16
19
|
## Anatomy
|
|
17
20
|
|
|
18
|
-
- Track: `--ws-
|
|
19
|
-
(`--
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
-
|
|
25
|
-
- Count (optional): a small pill after the label, white at 70% opacity on the current item.
|
|
21
|
+
- Track: the well (`--ws-well`, #EDEDED), no edge, 8 px corners (`--ws-radius-card`), 3 px inside (`--ws-halo`), items
|
|
22
|
+
2 px apart (`--space-3xs`). It sits at its own width (a flex column never stretches it), never wider than its column:
|
|
23
|
+
past that it scrolls sideways inside and fades at the edge that hides items.
|
|
24
|
+
- Item: 32 px (`--ws-control-h`) tall, 12 px sides, 6 px corners (`--ws-radius-row`), 13 / 18 medium navy words, a 16 px
|
|
25
|
+
icon 6 px before them; 40 px on a touch screen. The track is 38 tall (46 on touch).
|
|
26
|
+
- Current item: navy (`--color-text-heading`) with `--ws-on-act` words.
|
|
27
|
+
- Count: the item's own words after the label ("Needs a reply 10", 8 apart), numerals even; or inline ("Fix · 2").
|
|
26
28
|
|
|
27
29
|
## Variants and sizes
|
|
28
30
|
|
|
29
31
|
| Variant | What it looks like | Where |
|
|
30
32
|
| --- | --- | --- |
|
|
31
|
-
| Switch (default) |
|
|
32
|
-
| `tabs` | a real `role="tablist"`, each item a `tab` with `aria-selected
|
|
33
|
-
|
|
|
34
|
-
| `
|
|
35
|
-
| `
|
|
36
|
-
| `
|
|
33
|
+
| Switch (default) | the well track, buttons with `aria-pressed`, or links with `aria-current` | a mode or a filter kept on the page or in the URL |
|
|
34
|
+
| `tabs` | a real `role="tablist"`, each item a `tab` with `aria-selected` | a pane's sections (Seth's drawer tabs) |
|
|
35
|
+
| `--stretch` | each item an equal share of the width, never narrower than its words (past that the track scrolls) | a switch in a narrow card or on a phone |
|
|
36
|
+
| `--figures` | cream cells on the well, a name at the left (13 / 18 body grey) and a figure at the right (15 / 20 semibold navy), 40 tall, 10 / 14 inside; the current cell Seth's #2C4870; a row each when the track is too narrow for their names | a report's views, each with its number |
|
|
37
|
+
| `--clear` | no ground, so no side halo: the first and last items sit on the column's edges, in line with the rows; with `--stretch` | Seth's filter in a list head (Review inbox) |
|
|
38
|
+
| `--quiet` | the current item cream (`--ws-raised`) with navy words; in dark the tray a step lighter with the card edge inside, so it still shows on the dark well | beside the page's one navy act, so two navy things do not compete |
|
|
39
|
+
| `--sm` | North's filter size: a 28 px track on the surface with a 0.5 px edge inside, 2 in; items 24 tall, 10 sides, 4 px corners, 12 / 16 words | a page's period filter (`FilterBar`), the theme switch |
|
|
40
|
+
| `--dense` | 8 px sides | a row beside the chat |
|
|
41
|
+
| `__item--icon` | an icon alone, square (32; 28 by 24 in `sm`) with its name in `aria-label` | a chart's type, the theme switch |
|
|
42
|
+
|
|
43
|
+
`pills` (separate pills for the Team page's own top-level tabs) is a React-only look in the first product.
|
|
37
44
|
|
|
38
45
|
## States
|
|
39
46
|
|
|
40
|
-
- **Default:** the track at rest, the current item
|
|
41
|
-
- **Hover:** a non-current item
|
|
42
|
-
- **Focus:** the kit's
|
|
43
|
-
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
- **
|
|
47
|
-
-
|
|
48
|
-
- **
|
|
49
|
-
- **
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
- **
|
|
53
|
-
|
|
47
|
+
- **Default:** the track at rest, the current item in place.
|
|
48
|
+
- **Hover (a mouse only):** a non-current item takes the navy wash (`--ws-hover`); a figure cell a wash over its cream.
|
|
49
|
+
- **Focus:** the kit's ring, drawn inside the item (the track is a dense row). On the current item the ring takes the
|
|
50
|
+
fill's words colour (`--ws-on-act`), 2 px further in, so it shows on the navy (a radio group's focus always sits on its
|
|
51
|
+
chosen item); on `--quiet` it stays navy.
|
|
52
|
+
- **Pressed:** nothing moves (North).
|
|
53
|
+
- **Selected (current):** navy with cream words; `aria-selected="true"` (tabs), `aria-pressed="true"` (a switch),
|
|
54
|
+
`aria-current` (links), or a checked radio inside.
|
|
55
|
+
- **Pending / loading:** not applicable; switching is instant (a local or URL state).
|
|
56
|
+
- **Disabled:** an item that cannot be chosen is usually left out; one that is coming (a disabled button, or a disabled
|
|
57
|
+
radio inside) shows at 40% and takes no hover.
|
|
58
|
+
- **Error / empty:** not applicable; a group is never rendered with no items.
|
|
59
|
+
- **Long label:** items keep one line; a track too wide for its column scrolls inside with the edge fade. `figures`
|
|
60
|
+
cells wrap their names.
|
|
61
|
+
- **Narrow:** `--stretch` shares the width; `figures` cells take a row each; past four items on a phone, use a `Select`.
|
|
62
|
+
- **Touch:** items 40 tall, icon items 40 wide.
|
|
63
|
+
- **Dark:** the well, the hover wash and the act take their dark values; the figure cells' current is the act.
|
|
54
64
|
|
|
55
65
|
## Behaviour
|
|
56
66
|
|
|
57
|
-
- Keyboard: a switch is a
|
|
58
|
-
|
|
59
|
-
- Pointer / touch: tapping an item chooses it
|
|
60
|
-
- Motion: the thumb slides
|
|
61
|
-
|
|
67
|
+
- Keyboard: a switch is a group of buttons (Tab moves between them); `tabs` is one Tab stop and the arrow keys (plus
|
|
68
|
+
Home and End) move and choose, per the ARIA tabs pattern; native radios move with the arrow keys on their own.
|
|
69
|
+
- Pointer / touch: tapping an item chooses it.
|
|
70
|
+
- Motion: the navy thumb slides to each new choice (North's "Toggle pill slide", `springs.indicator` .38 / .16), plain
|
|
71
|
+
CSS with no script and no new markup. The chosen item is a CSS anchor; the track's `::before` is the thumb, its four
|
|
72
|
+
edges easing on motion's own `spring(.38, .16)` written out as `linear()` (700 ms, a 0.8% give;
|
|
73
|
+
`--ws-spring-indicator-duration` and `--ws-spring-indicator`). At rest the chosen item paints its own ground (the 0.4 look
|
|
74
|
+
and the real ground for contrast tools); while the track is pointed at or holds focus the thumb takes over that
|
|
75
|
+
ground, so a choice made then slides, and a choice made in mid-flight turns toward the new item from where the thumb
|
|
76
|
+
is. A resize or a late font, away from the pointer, lands it at once. The words turn over 250 ms
|
|
77
|
+
(`--ws-duration-text`). Without CSS anchor positioning the ground moves at once; under reduced motion everything is
|
|
78
|
+
still. `--figures` keeps its cells (each has its own ground). Try it in the preview: click any item.
|
|
62
79
|
|
|
63
80
|
## Content
|
|
64
81
|
|
|
65
82
|
- Short labels, sentence case, one or two words where possible ("Cold call", "This month").
|
|
66
|
-
- A count
|
|
67
|
-
- No em dashes
|
|
83
|
+
- A count is read as part of the item ("Needs a reply, 10").
|
|
84
|
+
- No em dashes.
|
|
68
85
|
|
|
69
86
|
## Props
|
|
70
87
|
|
|
71
88
|
| Name | Type | Meaning |
|
|
72
89
|
| --- | --- | --- |
|
|
73
|
-
| `label` | `string` | the group's own name (
|
|
74
|
-
| `items` | `SegmentedItem[]` | `key`, `label`, `href` or `onSelect`, `current`, `icon?`, `count?`, `
|
|
75
|
-
| `tabs` | `boolean` |
|
|
90
|
+
| `label` | `string` | the group's own name (`aria-label` on the switch, the `nav` or the `tablist`) |
|
|
91
|
+
| `items` | `SegmentedItem[]` | `key`, `label`, `href` or `onSelect`, `current`, `icon?`, `count?`, `figure?`, `ariaLabel?`, `title?`, and (`tabs`) `id`/`controls` |
|
|
92
|
+
| `tabs` | `boolean` | a real tab row instead of a switch |
|
|
76
93
|
| `stretch` | `boolean \| 'always'` | fills the width on a phone, or at every width |
|
|
77
|
-
| `
|
|
78
|
-
| `
|
|
79
|
-
| `
|
|
94
|
+
| `size` | `'medium' \| 'small'` | `small` is the 28 px filter size |
|
|
95
|
+
| `figures` | `boolean` | Seth's view tabs |
|
|
96
|
+
| `clear`, `quiet`, `dense` | `boolean` | the looks above |
|
|
80
97
|
| `className` | `string` | layout only |
|
|
81
98
|
|
|
82
99
|
## Rules
|
|
83
100
|
|
|
84
|
-
- Every switch and tab row
|
|
85
|
-
draws its own
|
|
86
|
-
- `tabs` is a real tablist: `role="tablist"`,
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
- `
|
|
101
|
+
- Every switch and tab row of two to four items is `Segmented`, so the current item always moves the same way; a screen
|
|
102
|
+
never draws its own (13 Oct 2026).
|
|
103
|
+
- `tabs` is a real tablist: `role="tablist"`, `tab`s with `aria-selected`, arrows, Home and End.
|
|
104
|
+
- The track is Seth's well (D1): #EDEDED, no edge, 8 / 6 corners, 3 in, 2 apart; the 0.4.0 cream track with a hairline
|
|
105
|
+
is gone.
|
|
106
|
+
- `--quiet` exists so a switch never competes with the page's one navy act.
|
|
107
|
+
- More than four items on a phone become a `Select`.
|
|
90
108
|
|
|
91
109
|
## Source
|
|
92
110
|
|
|
93
|
-
**Derived from**:
|
|
94
|
-
|
|
111
|
+
**Derived from**: Seth's well switch (Grow drawer tabs 301:2069; Review inbox filter 313:2737-2743: 3 in, 2 apart, 8 / 6
|
|
112
|
+
corners, 32 px items, 13 / 18 words, navy current with cream words) and his view tabs (301:1658: cream cells, a name and
|
|
113
|
+
a figure, the #2C4870 current). North's filter size (style1.css:804-808) for `sm` and its indicator spring. The geometry
|
|
114
|
+
check's fixes: the stretch in a flex column, the 0 px icons, the touch height.
|
|
115
|
+
|
|
116
|
+
## Markup
|
|
117
|
+
|
|
118
|
+
```html
|
|
119
|
+
<div class="ws-segmented" role="group" aria-label="Call kind">
|
|
120
|
+
<button type="button" class="ws-segmented__item" aria-pressed="true">Cold call</button>
|
|
121
|
+
<button type="button" class="ws-segmented__item" aria-pressed="false">Live transfer</button>
|
|
122
|
+
</div>
|
|
123
|
+
|
|
124
|
+
<div class="ws-segmented ws-segmented--figures" role="tablist" aria-label="Audit report">
|
|
125
|
+
<button type="button" role="tab" aria-selected="true" class="ws-segmented__item">Your score<span class="ws-segmented__figure">72</span></button>
|
|
126
|
+
<button type="button" role="tab" aria-selected="false" tabindex="-1" class="ws-segmented__item">Compared against other teams<span class="ws-segmented__figure">1 of 5</span></button>
|
|
127
|
+
</div>
|
|
128
|
+
|
|
129
|
+
<div class="ws-segmented" role="radiogroup" aria-label="Call length">
|
|
130
|
+
<label class="ws-segmented__item"><input type="radio" name="len" value="30" checked>30 min</label>
|
|
131
|
+
<label class="ws-segmented__item"><input type="radio" name="len" value="60">An hour</label>
|
|
132
|
+
</div>
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Styles
|
|
136
|
+
|
|
137
|
+
`design-system/components/Segmented/style.css`: `ws-segmented` with `--stretch`, `--figures`, `--clear`, `--quiet`,
|
|
138
|
+
`--sm`, `--dense`; `ws-segmented__item` (and `--icon`), `__count`, `__figure`. The edge fade is the scroll-driven
|
|
139
|
+
`ws-scroll-edges` (shared with `Tabs`); touch heights come from the house's touch block.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<!-- @dsCard group="Actions" height=
|
|
1
|
+
<!-- @dsCard group="Actions" height=760 -->
|
|
2
2
|
<!doctype html>
|
|
3
3
|
<html>
|
|
4
4
|
<head>
|
|
@@ -11,48 +11,129 @@
|
|
|
11
11
|
<div class="ws-stage ws-stage--column">
|
|
12
12
|
|
|
13
13
|
<div class="ws-stack">
|
|
14
|
-
<span class="ws-muted">
|
|
14
|
+
<span class="ws-muted">The well switch: 3 px in, 2 apart, 32 px items, navy current (Seth's drawer tabs). Click any item on this page: the thumb slides to it on North's toggle pill spring</span>
|
|
15
15
|
<div class="ws-segmented" role="group" aria-label="Call kind">
|
|
16
|
-
<button type="button" class="ws-segmented__item" aria-
|
|
17
|
-
<button type="button" class="ws-segmented__item">Live transfer</button>
|
|
18
|
-
<button type="button" class="ws-segmented__item">Follow-up</button>
|
|
16
|
+
<button type="button" class="ws-segmented__item" aria-pressed="true">Cold call</button>
|
|
17
|
+
<button type="button" class="ws-segmented__item" aria-pressed="false">Live transfer</button>
|
|
18
|
+
<button type="button" class="ws-segmented__item" aria-pressed="false">Follow-up</button>
|
|
19
19
|
</div>
|
|
20
20
|
</div>
|
|
21
21
|
|
|
22
22
|
<div class="ws-stack">
|
|
23
|
-
<span class="ws-muted">A tab row (role="tablist"
|
|
24
|
-
<ul role="tablist" aria-label="
|
|
25
|
-
<li role="presentation"><button role="tab" id="tab-
|
|
26
|
-
<li role="presentation"><button role="tab" id="tab-
|
|
27
|
-
<li role="presentation"><button role="tab" id="tab-
|
|
23
|
+
<span class="ws-muted">A tab row (role="tablist") with a count in the words</span>
|
|
24
|
+
<ul role="tablist" aria-label="Local search" class="ws-segmented">
|
|
25
|
+
<li role="presentation"><button role="tab" id="tab-where" aria-controls="panel-where" aria-selected="true" tabindex="0" class="ws-segmented__item">Where we checked</button></li>
|
|
26
|
+
<li role="presentation"><button role="tab" id="tab-why" aria-controls="panel-why" aria-selected="false" tabindex="-1" class="ws-segmented__item">Why</button></li>
|
|
27
|
+
<li role="presentation"><button role="tab" id="tab-fix" aria-controls="panel-fix" aria-selected="false" tabindex="-1" class="ws-segmented__item">Fix · 2</button></li>
|
|
28
|
+
<li role="presentation"><button role="tab" id="tab-found" aria-controls="panel-found" aria-selected="false" tabindex="-1" class="ws-segmented__item">Found</button></li>
|
|
28
29
|
</ul>
|
|
29
30
|
</div>
|
|
30
31
|
|
|
32
|
+
<div class="ws-stack" style="width: 360px; max-width: 100%;">
|
|
33
|
+
<span class="ws-muted">Stretched (equal shares), and clear: Seth's filter in a list head, no ground</span>
|
|
34
|
+
<div class="ws-segmented ws-segmented--stretch" role="group" aria-label="Report range">
|
|
35
|
+
<button type="button" class="ws-segmented__item" aria-pressed="false">This week</button>
|
|
36
|
+
<button type="button" class="ws-segmented__item" aria-pressed="true">This month</button>
|
|
37
|
+
<button type="button" class="ws-segmented__item" aria-pressed="false">All time</button>
|
|
38
|
+
</div>
|
|
39
|
+
<div class="ws-segmented ws-segmented--stretch ws-segmented--clear" role="group" aria-label="Reviews">
|
|
40
|
+
<button type="button" class="ws-segmented__item" aria-pressed="true">Needs a reply<span class="ws-segmented__count">10</span></button>
|
|
41
|
+
<button type="button" class="ws-segmented__item" aria-pressed="false">All<span class="ws-segmented__count">100</span></button>
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
44
|
+
|
|
31
45
|
<div class="ws-stack">
|
|
32
|
-
<span class="ws-muted">
|
|
33
|
-
<div
|
|
34
|
-
<
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
46
|
+
<span class="ws-muted">Figures: Seth's view tabs (a name at the left, its figure at the right; a row each when narrow)</span>
|
|
47
|
+
<div class="ws-segmented ws-segmented--figures" role="tablist" aria-label="Audit report">
|
|
48
|
+
<button type="button" role="tab" aria-selected="true" class="ws-segmented__item">Your score<span class="ws-segmented__figure">72</span></button>
|
|
49
|
+
<button type="button" role="tab" aria-selected="false" tabindex="-1" class="ws-segmented__item">Compared against other teams<span class="ws-segmented__figure">1 of 5</span></button>
|
|
50
|
+
<button type="button" role="tab" aria-selected="false" tabindex="-1" class="ws-segmented__item">Which AI platforms mention you<span class="ws-segmented__figure">10 of 16</span></button>
|
|
51
|
+
</div>
|
|
52
|
+
</div>
|
|
53
|
+
|
|
54
|
+
<div class="ws-cluster ws-cluster--loose ws-cluster--start">
|
|
55
|
+
<div class="ws-stack">
|
|
56
|
+
<span class="ws-muted">Small: North's filter size (28 px track)</span>
|
|
57
|
+
<div class="ws-segmented ws-segmented--sm" role="group" aria-label="Period">
|
|
58
|
+
<button type="button" class="ws-segmented__item" aria-pressed="false">Week</button>
|
|
59
|
+
<button type="button" class="ws-segmented__item" aria-pressed="true">Month</button>
|
|
60
|
+
<button type="button" class="ws-segmented__item" aria-pressed="false">Quarter</button>
|
|
61
|
+
<button type="button" class="ws-segmented__item" aria-pressed="false">Year</button>
|
|
62
|
+
</div>
|
|
63
|
+
</div>
|
|
64
|
+
<div class="ws-stack">
|
|
65
|
+
<span class="ws-muted">Quiet (beside the page's navy act)</span>
|
|
66
|
+
<div class="ws-segmented ws-segmented--quiet" role="group" aria-label="Show">
|
|
67
|
+
<button type="button" class="ws-segmented__item" aria-pressed="true">Open</button>
|
|
68
|
+
<button type="button" class="ws-segmented__item" aria-pressed="false">Done</button>
|
|
69
|
+
</div>
|
|
70
|
+
</div>
|
|
71
|
+
<div class="ws-stack">
|
|
72
|
+
<span class="ws-muted">Dense (8 px sides), with an item that cannot be chosen yet (40%)</span>
|
|
73
|
+
<div class="ws-segmented ws-segmented--dense" role="group" aria-label="Reply as">
|
|
74
|
+
<button type="button" class="ws-segmented__item" aria-pressed="true">Text</button>
|
|
75
|
+
<button type="button" class="ws-segmented__item" aria-pressed="false">Email</button>
|
|
76
|
+
<button type="button" class="ws-segmented__item" aria-pressed="false" disabled>Voice</button>
|
|
77
|
+
</div>
|
|
78
|
+
</div>
|
|
79
|
+
<div class="ws-stack">
|
|
80
|
+
<span class="ws-muted">With icons, and icons alone</span>
|
|
81
|
+
<div class="ws-cluster">
|
|
82
|
+
<div class="ws-segmented" role="group" aria-label="View">
|
|
83
|
+
<button type="button" class="ws-segmented__item" aria-pressed="true">
|
|
84
|
+
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="2" y="2" width="5" height="5" rx="1"/><rect x="9" y="2" width="5" height="5" rx="1"/><rect x="2" y="9" width="5" height="5" rx="1"/><rect x="9" y="9" width="5" height="5" rx="1"/></svg>
|
|
85
|
+
Board
|
|
86
|
+
</button>
|
|
87
|
+
<button type="button" class="ws-segmented__item" aria-pressed="false">
|
|
88
|
+
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M2 4h12M2 8h12M2 12h12"/></svg>
|
|
89
|
+
List
|
|
90
|
+
</button>
|
|
91
|
+
</div>
|
|
92
|
+
<div class="ws-segmented" role="group" aria-label="Chart">
|
|
93
|
+
<button type="button" class="ws-segmented__item ws-segmented__item--icon" aria-pressed="true" aria-label="Bars" title="Bars">
|
|
94
|
+
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" aria-hidden="true"><path d="M4 13V8M8 13V3M12 13V6"/></svg>
|
|
95
|
+
</button>
|
|
96
|
+
<button type="button" class="ws-segmented__item ws-segmented__item--icon" aria-pressed="false" aria-label="Line" title="Line">
|
|
97
|
+
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M2 12l4-4 3 2 5-6"/></svg>
|
|
98
|
+
</button>
|
|
99
|
+
</div>
|
|
38
100
|
</div>
|
|
39
101
|
</div>
|
|
40
102
|
</div>
|
|
41
103
|
|
|
42
104
|
<div class="ws-stack">
|
|
43
|
-
<span class="ws-muted">
|
|
44
|
-
<div class="ws-segmented" role="
|
|
45
|
-
<
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
105
|
+
<span class="ws-muted">A form's choice: native radios inside the items (arrow keys move the choice)</span>
|
|
106
|
+
<div class="ws-segmented" role="radiogroup" aria-label="Call length">
|
|
107
|
+
<label class="ws-segmented__item"><input type="radio" name="len" value="15">15 min</label>
|
|
108
|
+
<label class="ws-segmented__item"><input type="radio" name="len" value="30" checked>30 min</label>
|
|
109
|
+
<label class="ws-segmented__item"><input type="radio" name="len" value="60">An hour</label>
|
|
110
|
+
</div>
|
|
111
|
+
</div>
|
|
112
|
+
|
|
113
|
+
<div class="ws-stack" style="width: 300px; max-width: 100%;">
|
|
114
|
+
<span class="ws-muted">Too many for its column: the track scrolls inside (on a phone, past four, use a Select)</span>
|
|
115
|
+
<div class="ws-segmented" role="group" aria-label="Stage">
|
|
116
|
+
<button type="button" class="ws-segmented__item" aria-pressed="false">New</button>
|
|
117
|
+
<button type="button" class="ws-segmented__item" aria-pressed="true">Quote sent</button>
|
|
118
|
+
<button type="button" class="ws-segmented__item" aria-pressed="false">Signed</button>
|
|
119
|
+
<button type="button" class="ws-segmented__item" aria-pressed="false">Closed won</button>
|
|
120
|
+
<button type="button" class="ws-segmented__item" aria-pressed="false">Closed lost</button>
|
|
53
121
|
</div>
|
|
54
122
|
</div>
|
|
55
123
|
|
|
56
124
|
</div>
|
|
125
|
+
<script>
|
|
126
|
+
/* The demo's wiring: a click chooses the item (an app keeps the choice; the kit only draws it, and the thumb slides on
|
|
127
|
+
its own). The radios choose themselves. */
|
|
128
|
+
document.addEventListener('click', (e) => {
|
|
129
|
+
const item = e.target.closest('button.ws-segmented__item');
|
|
130
|
+
const attr = item && !item.disabled && ['aria-pressed', 'aria-selected', 'aria-current'].find((a) => item.hasAttribute(a));
|
|
131
|
+
if (!attr) return;
|
|
132
|
+
for (const i of item.closest('.ws-segmented').querySelectorAll('.ws-segmented__item')) {
|
|
133
|
+
i.setAttribute(attr, String(i === item));
|
|
134
|
+
if (attr === 'aria-selected') i.tabIndex = i === item ? 0 : -1;
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
</script>
|
|
57
138
|
</body>
|
|
58
139
|
</html>
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/* ---- Segmented: Seth's well switch (0.5.0, D1; 301:2069, 313:2737): the #EDEDED well with no edge, 8 px corners, 3 px
|
|
2
|
+
inside, items 2 apart, 32 tall, 6 px corners, 13 / 18 medium navy words; the current item navy with cream words. It
|
|
3
|
+
sits at its own width (a flex column never stretches it), never wider than its column (it scrolls inside, never
|
|
4
|
+
clipping its inset focus ring). Restates the house's Segmented block, so that copy can go. ---- */
|
|
5
|
+
.ws-segmented { display: inline-flex; align-self: flex-start; max-width: 100%; overflow-x: auto; scrollbar-width: none; padding: var(--ws-halo); gap: var(--space-3xs); border-radius: var(--ws-radius-card); background: var(--ws-well); box-shadow: none; }
|
|
6
|
+
.ws-segmented::-webkit-scrollbar { display: none; }
|
|
7
|
+
/* Wider than its column, the track fades at the edge that hides items (the house ws-scroll-edges fade; nothing when it fits). */
|
|
8
|
+
@supports (animation-timeline: scroll()) {
|
|
9
|
+
.ws-segmented { mask-image: linear-gradient(90deg, transparent, currentColor var(--ws-fade-start), currentColor calc(100% - var(--ws-fade-end)), transparent); animation: ws-scroll-edges linear; animation-timeline: scroll(self inline); }
|
|
10
|
+
}
|
|
11
|
+
.ws-segmented > li { display: flex; }
|
|
12
|
+
.ws-segmented__item { position: relative; display: inline-flex; flex-shrink: 0; align-items: center; justify-content: center; gap: var(--space-xxs-plus); height: var(--ws-control-h); padding: 0 var(--space-sm); border: 0; border-radius: var(--ws-radius-row); background-color: transparent; color: var(--color-text-heading); font-size: var(--ws-text-control); line-height: var(--ws-leading-control); font-weight: 500; white-space: nowrap; cursor: pointer; }
|
|
13
|
+
.ws-segmented__item svg { flex-shrink: 0; width: var(--ws-icon); height: var(--ws-icon); }
|
|
14
|
+
/* A count inside an item ("Fix · 2", "Needs a reply 10"): the item's own words, 8 from the label, numerals even. */
|
|
15
|
+
.ws-segmented__count { margin-inline-start: var(--space-3xs); font-variant-numeric: tabular-nums; }
|
|
16
|
+
/* An item can hold a native radio (a form's choice, the theme switch): the label is the target, the input is hidden. */
|
|
17
|
+
.ws-segmented__item > input { position: absolute; width: var(--ws-line); height: var(--ws-line); margin: 0; opacity: 0; pointer-events: none; }
|
|
18
|
+
.ws-segmented__item:has(> input:focus-visible) { outline: var(--ws-focus-width) solid var(--ws-focus-color); outline-offset: calc(var(--ws-focus-width) * -1); }
|
|
19
|
+
@media (hover: hover) {
|
|
20
|
+
.ws-segmented__item:not(:where(:disabled, :has(> input:disabled))):hover { background-color: var(--ws-hover); color: var(--color-text-heading); }
|
|
21
|
+
}
|
|
22
|
+
/* The current item paints its own ground over the hover beat. Where the browser anchors (Motion, at the end), one thumb
|
|
23
|
+
under the items paints it instead and slides to each new choice. */
|
|
24
|
+
.ws-segmented__item[aria-selected="true"], .ws-segmented__item[aria-current]:not([aria-current="false"]), .ws-segmented__item[aria-checked="true"], .ws-segmented__item[aria-pressed="true"], .ws-segmented__item:has(> input:checked) { background-color: var(--color-text-heading); color: var(--ws-on-act); }
|
|
25
|
+
.ws-segmented__item:has(> input:disabled), .ws-segmented__item:disabled { opacity: 0.4; cursor: not-allowed; }
|
|
26
|
+
/* Focus on the current item: a navy ring on a navy fill would vanish (and a radio group's focus always sits on its
|
|
27
|
+
chosen item), so the ring there is the fill's own words colour, 2 px further in. */
|
|
28
|
+
.ws-segmented__item:is([aria-selected="true"], [aria-current]:not([aria-current="false"]), [aria-checked="true"], [aria-pressed="true"]):focus-visible, .ws-segmented__item:has(> input:checked:focus-visible) { outline-color: var(--ws-on-act); outline-offset: calc(var(--ws-focus-width) * -2); }
|
|
29
|
+
|
|
30
|
+
/* stretch: equal shares of the width, never narrower than an item's words (past that the track scrolls). clear: no
|
|
31
|
+
ground (Seth's filter in a list head). quiet: the current item cream (the raised ground, so it still shows on the
|
|
32
|
+
dark well) with navy words, beside the page's one navy act. dense: tighter sides beside the chat. */
|
|
33
|
+
.ws-segmented--stretch { display: flex; align-self: stretch; }
|
|
34
|
+
.ws-segmented--stretch > * { flex: 1 1 0; }
|
|
35
|
+
/* A clear track has no ground to hold its 3 px halo, so the halo keeps only its height: the first and last items sit on
|
|
36
|
+
the column's edges, in line with the rows and words above and below (Seth's track p 3 with no fill showed only as a
|
|
37
|
+
3 px miss). */
|
|
38
|
+
.ws-segmented--clear { padding-inline: 0; background: transparent; }
|
|
39
|
+
.ws-segmented--dense .ws-segmented__item { padding: 0 var(--space-xs); }
|
|
40
|
+
/* In dark the raised ground is barely off the well (1.14:1), so there the chosen item takes the tray, a step lighter,
|
|
41
|
+
with the card edge inside it (derived: Seth draws only light). */
|
|
42
|
+
.ws-segmented--quiet { --ws-segmented-quiet: var(--ws-raised); --ws-segmented-quiet-edge: transparent; }
|
|
43
|
+
[data-theme="dark"] .ws-segmented--quiet { --ws-segmented-quiet: var(--ws-tray); --ws-segmented-quiet-edge: var(--ws-edge-card); }
|
|
44
|
+
@media (prefers-color-scheme: dark) { [data-theme="system"] .ws-segmented--quiet { --ws-segmented-quiet: var(--ws-tray); --ws-segmented-quiet-edge: var(--ws-edge-card); } }
|
|
45
|
+
.ws-segmented--quiet .ws-segmented__item:is([aria-selected="true"], [aria-current]:not([aria-current="false"]), [aria-checked="true"], [aria-pressed="true"], :has(> input:checked)) { background-color: var(--ws-segmented-quiet); box-shadow: inset 0 0 0 var(--ws-hairline) var(--ws-segmented-quiet-edge); color: var(--color-text-heading); }
|
|
46
|
+
.ws-segmented--quiet .ws-segmented__item:is([aria-selected="true"], [aria-current]:not([aria-current="false"]), [aria-checked="true"], [aria-pressed="true"]):focus-visible, .ws-segmented--quiet .ws-segmented__item:has(> input:checked:focus-visible) { outline-color: var(--ws-focus-color); outline-offset: calc(var(--ws-focus-width) * -1); }
|
|
47
|
+
/* sm: North's filter size (style1.css:804): a 28 px track on the surface with the 0.5 px edge inside, 2 in, items
|
|
48
|
+
24 tall, 10 sides, 4 px corners, 12 / 16 words. */
|
|
49
|
+
.ws-segmented--sm { padding: var(--space-3xs); border-radius: var(--ws-radius-row); background: var(--color-surface); box-shadow: var(--ws-shadow-hairline-in); }
|
|
50
|
+
.ws-segmented--sm .ws-segmented__item { height: var(--space-lg); padding: 0 var(--space-xs-plus); border-radius: var(--ws-radius-control); font-size: var(--ws-text-dense); line-height: var(--space-md); }
|
|
51
|
+
/* An item that is an icon alone (its name in aria-label): square, 32 (28 by 24 in sm). */
|
|
52
|
+
.ws-segmented__item--icon { width: var(--ws-control-h); padding: 0; }
|
|
53
|
+
.ws-segmented--sm .ws-segmented__item--icon { width: var(--ws-control-h-sm); padding: 0; }
|
|
54
|
+
|
|
55
|
+
/* figures: Seth's view tabs (301:1658): each item a cream cell, its name at the left (13 / 18 body grey) and its figure
|
|
56
|
+
at the right (15 / 20 semibold navy), 40 tall, 10 / 14 inside. The current cell is Seth's #2C4870 (light; the act in
|
|
57
|
+
dark) with cream words. Cells wrap to a row each when the track is too narrow for three names. */
|
|
58
|
+
.ws-segmented--figures { display: flex; flex-wrap: wrap; align-self: stretch; overflow: visible; mask-image: none; animation: none; }
|
|
59
|
+
.ws-segmented--figures > * { flex: 1 1 var(--space-9xl); min-width: 0; }
|
|
60
|
+
.ws-segmented--figures .ws-segmented__item { justify-content: space-between; gap: var(--space-sm); height: auto; min-height: var(--space-2xl); padding: var(--space-xs-plus) var(--space-sm-plus); background-color: var(--ws-raised); color: var(--color-text-body); white-space: normal; text-align: start; }
|
|
61
|
+
.ws-segmented__figure { flex-shrink: 0; font-size: var(--ws-text-section); line-height: var(--ws-leading-row); font-weight: 600; color: var(--color-text-heading); font-variant-numeric: tabular-nums; white-space: nowrap; }
|
|
62
|
+
@media (hover: hover) {
|
|
63
|
+
.ws-segmented--figures .ws-segmented__item:hover { background-image: linear-gradient(var(--ws-hover), var(--ws-hover)); }
|
|
64
|
+
}
|
|
65
|
+
.ws-segmented--figures .ws-segmented__item:is([aria-selected="true"], [aria-current]:not([aria-current="false"]), [aria-checked="true"], [aria-pressed="true"], :has(> input:checked)) { background-color: var(--ws-agent-tally); background-image: none; color: var(--ws-on-act); }
|
|
66
|
+
.ws-segmented--figures .ws-segmented__item:is([aria-selected="true"], [aria-current]:not([aria-current="false"]), [aria-checked="true"], [aria-pressed="true"], :has(> input:checked)) .ws-segmented__figure { color: inherit; }
|
|
67
|
+
@media (pointer: coarse) { .ws-segmented__item--icon, .ws-segmented--sm .ws-segmented__item--icon { min-width: var(--ws-touch); } }
|
|
68
|
+
|
|
69
|
+
/* ---- Motion: North's "Toggle pill slide" (springs.indicator, .38 / .16; north-motion 3). A thumb slides to each new
|
|
70
|
+
choice instead of the ground jumping from item to item. The chosen item is the anchor (CSS anchor positioning) and
|
|
71
|
+
the track's ::before is the thumb, under the items, its four edges easing on motion's own spring(.38, .16) written
|
|
72
|
+
out as linear() (motion's toString: 700 ms, a 0.8% give). At rest the chosen item paints its own ground, so a resting
|
|
73
|
+
track is the 0.4 track pixel for pixel (and every contrast tool reads the real ground); while the track is pointed at
|
|
74
|
+
or holds focus the thumb takes over that ground (the same box, the same paint, at once), so a choice made then
|
|
75
|
+
slides. Only a real choice moves it (North: the pill moves only on a real selection); a resize or a late font, away
|
|
76
|
+
from the pointer, lands at once. No new markup, so a 0.4 track slides too. Without anchor positioning, or under
|
|
77
|
+
reduced motion, the ground moves at once. --figures keeps its cells: each has its own ground. The words turn over
|
|
78
|
+
250 ms (North css:150).
|
|
79
|
+
The spring is the global --ws-spring-indicator over --ws-spring-indicator-duration. ---- */
|
|
80
|
+
@supports (anchor-name: --a) {
|
|
81
|
+
.ws-segmented:not(.ws-segmented--figures) { position: relative; anchor-scope: --ws-segmented-thumb; }
|
|
82
|
+
.ws-segmented:not(.ws-segmented--figures)::before { content: ""; position: absolute; position-anchor: --ws-segmented-thumb; inset: anchor(top) anchor(right) anchor(bottom) anchor(left); border-radius: var(--ws-radius-row); background: var(--color-text-heading); opacity: 0; pointer-events: none; }
|
|
83
|
+
.ws-segmented--sm:not(.ws-segmented--figures)::before { border-radius: var(--ws-radius-control); }
|
|
84
|
+
.ws-segmented--quiet:not(.ws-segmented--figures)::before { background: var(--ws-segmented-quiet); box-shadow: inset 0 0 0 var(--ws-hairline) var(--ws-segmented-quiet-edge); }
|
|
85
|
+
.ws-segmented:not(.ws-segmented--figures) .ws-segmented__item:is([aria-selected="true"], [aria-current]:not([aria-current="false"]), [aria-checked="true"], [aria-pressed="true"], :has(> input:checked)) { anchor-name: --ws-segmented-thumb; }
|
|
86
|
+
}
|
|
87
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
88
|
+
.ws-segmented__item { transition: background-color var(--ws-duration-hover) var(--ws-ease-soft), color var(--ws-duration-text) var(--ws-ease-soft); }
|
|
89
|
+
@supports (anchor-name: --a) {
|
|
90
|
+
.ws-segmented:not(.ws-segmented--figures):is(:hover, :focus-within)::before { opacity: 1; transition: inset var(--ws-spring-indicator-duration) var(--ws-spring-indicator); }
|
|
91
|
+
.ws-segmented:not(.ws-segmented--figures):is(:hover, :focus-within) .ws-segmented__item:is([aria-selected="true"], [aria-current]:not([aria-current="false"]), [aria-checked="true"], [aria-pressed="true"], :has(> input:checked)) { background-color: transparent; box-shadow: none; }
|
|
92
|
+
.ws-segmented:not(.ws-segmented--figures) .ws-segmented__item:is([aria-selected="true"], [aria-current]:not([aria-current="false"]), [aria-checked="true"], [aria-pressed="true"], :has(> input:checked)) { transition: color var(--ws-duration-text) var(--ws-ease-soft); }
|
|
93
|
+
}
|
|
94
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
Progress split by area and by step: Seth's "1 of 6" figure, a line under it, and one bar of segments with each area named.
|
|
2
|
+
|
|
3
|
+
**Use it when**
|
|
4
|
+
|
|
5
|
+
- A checklist's progress has a few areas, each with its own steps (fixes by Website, Social, Local search), and the
|
|
6
|
+
page opens on how far along the whole thing is.
|
|
7
|
+
- The reader should see both the total ("1 of 6") and where the done steps are.
|
|
8
|
+
|
|
9
|
+
**Not for**
|
|
10
|
+
|
|
11
|
+
- One share with no areas: use `TickStrip` or `Meter`.
|
|
12
|
+
- Ordered steps someone walks through: use `Stepper`.
|
|
13
|
+
- A score: use `ScoreHero`.
|
|
14
|
+
|
|
15
|
+
**Anatomy**
|
|
16
|
+
|
|
17
|
+
- A column, 6 apart (`--space-xxs-plus`): the figure (`ws-figure ws-figure--pane`, 44/48 regular navy, proportional
|
|
18
|
+
numerals so its ink sits on the bar's edge), the line (14/20 `--color-text-body`), the areas.
|
|
19
|
+
- Areas: equal columns 12 apart, at least 96 wide, so on a narrow column they wrap onto the same columns (16 between
|
|
20
|
+
rows). Each area is a `TickStrip --bar` (one segment a step: 12 tall, 4 apart, 2 px corners; done teal, the rest the
|
|
21
|
+
track) and 8 under it its label (13/18 medium `--color-text-muted`, one line, a `title` when it can truncate).
|
|
22
|
+
|
|
23
|
+
**States**
|
|
24
|
+
|
|
25
|
+
- Default: done segments in teal.
|
|
26
|
+
- Draw (`--draw` on a strip, `--i` on each lit segment): segments rise in as the card's draw.
|
|
27
|
+
- Nothing done: every segment the track; the figure says "0 of 6".
|
|
28
|
+
- Long label: truncates with its `title`.
|
|
29
|
+
- Reduced motion: in place.
|
|
30
|
+
- Hover, focus: none; each area's list below the bar is where people act.
|
|
31
|
+
|
|
32
|
+
**Behaviour**
|
|
33
|
+
|
|
34
|
+
- The `<section>` carries `aria-label` with the total and each area ("1 of 6 fixes done: Website 0 of 2 ..."); the
|
|
35
|
+
areas are `aria-hidden`.
|
|
36
|
+
|
|
37
|
+
**Rules**
|
|
38
|
+
|
|
39
|
+
- Areas keep the order of the list below them, so the bar is a map of the page.
|
|
40
|
+
- Equal widths, whatever each area's count (Seth's frame holds two a group, so a width by count is unknown).
|
|
41
|
+
- One tone: done is teal; there is no partial tone.
|
|
42
|
+
|
|
43
|
+
**Source**
|
|
44
|
+
|
|
45
|
+
**Seth**: Fixes checklist, "Progress by area" (308:2481 to 308:2501): figure, line and bar 6 apart, areas 12 apart,
|
|
46
|
+
segments 4 apart and 12 tall, labels 8 under.
|
|
47
|
+
|
|
48
|
+
**Markup**
|
|
49
|
+
|
|
50
|
+
```html
|
|
51
|
+
<section class="ws-segmented-progress" aria-label="1 of 6 fixes done: Website 0 of 2, Social 1 of 2, Local search 0 of 2">
|
|
52
|
+
<p class="ws-figure ws-figure--pane">1 of 6</p>
|
|
53
|
+
<p class="ws-segmented-progress__line">From your Nov 2 audit.</p>
|
|
54
|
+
<div class="ws-segmented-progress__areas" aria-hidden="true">
|
|
55
|
+
<div class="ws-segmented-progress__area">
|
|
56
|
+
<div class="ws-tick-strip ws-tick-strip--bar" style="--n: 2;"><span class="ws-tick-strip__tick ws-tick-strip__tick--on"></span><span class="ws-tick-strip__tick"></span></div>
|
|
57
|
+
<span class="ws-segmented-progress__label">Social</span>
|
|
58
|
+
</div>
|
|
59
|
+
</div>
|
|
60
|
+
</section>
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
**Styles**: `SegmentedProgress/style.css` (with `TickStrip/style.css`), in `bundle.css` and `fello.css` as
|
|
64
|
+
`.ws-segmented-progress`. Every value is a token.
|