@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
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/* ---- Composer: the one chat box (North's): a square-cornered field 52 tall that grows with the words, its tools on the bottom line, a context tab riding on top ---- */
|
|
2
|
+
/* The field: white, the 0.5 px card edge, 4 px corners, 52 at least, 8 inside (16 on the left of the words). It grows
|
|
3
|
+
with the words and its tools stay on the bottom line. Focus draws the kit's 2 px navy ring on the box's own edge
|
|
4
|
+
(inside it, so the composer area never has to make room for it). */
|
|
5
|
+
.ws-composer { --ws-composer-line: var(--ws-control-h-md); display: flex; align-items: flex-end; gap: var(--space-3xs); min-height: var(--ws-composer-h); padding: var(--space-xs) var(--space-xs) var(--space-xs) var(--space-md); border-radius: var(--ws-radius-control); background: var(--ws-field); box-shadow: inset 0 0 0 var(--ws-hairline) var(--ws-edge-card); color: var(--ws-field-ink); }
|
|
6
|
+
.ws-composer:has(.ws-composer__words:focus-visible) { outline: var(--ws-focus-width) solid var(--ws-focus-color); outline-offset: calc(var(--ws-focus-width) * -1); }
|
|
7
|
+
.ws-composer__words:focus-visible { outline: none; }
|
|
8
|
+
.ws-composer--live { box-shadow: inset 0 0 0 var(--ws-hairline) var(--ws-edge-card), var(--ws-ring-selected); }
|
|
9
|
+
/* The lead (the home screen's address line): the app's 20 px face and short name, then a 1 px rule, on the tools' line. */
|
|
10
|
+
.ws-composer__lead { display: flex; flex-shrink: 0; align-items: center; gap: var(--space-xs); height: var(--ws-composer-line); }
|
|
11
|
+
.ws-composer__face { flex-shrink: 0; width: var(--ws-icon-lg); height: var(--ws-icon-lg); }
|
|
12
|
+
.ws-composer__face svg { width: var(--ws-icon-sm); height: var(--ws-icon-sm); }
|
|
13
|
+
.ws-composer__name { font-size: var(--ws-text-body); font-weight: 500; color: var(--color-text-heading); white-space: nowrap; }
|
|
14
|
+
.ws-composer__rule { flex-shrink: 0; align-self: flex-end; width: var(--ws-line); height: var(--ws-icon-lg); margin: 0 var(--space-sm) calc((var(--ws-composer-line) - var(--ws-icon-lg)) / 2); background: var(--ws-track); }
|
|
15
|
+
/* The words: 16 / 24, one line 36 tall (6 above and under, centred on the tools' line), growing to 6 lines then scrolling. */
|
|
16
|
+
.ws-composer__words { flex: 1; min-width: 0; min-height: var(--ws-composer-line); max-height: var(--space-8xl); margin: 0; padding: calc((var(--ws-composer-line) - var(--ws-leading-message)) / 2) var(--space-3xs) calc((var(--ws-composer-line) - var(--ws-leading-message)) / 2) 0; border: 0; background: transparent; font-size: var(--ws-text-value); line-height: var(--ws-leading-message); color: var(--ws-field-ink); resize: none; field-sizing: content; overflow-wrap: anywhere; }
|
|
17
|
+
textarea.ws-composer__words { overflow-y: auto; }
|
|
18
|
+
/* A one-line field (an input) cuts its words and its placeholder with an ellipsis, never mid-letter. */
|
|
19
|
+
input.ws-composer__words { text-overflow: ellipsis; }
|
|
20
|
+
.ws-composer__words::placeholder, .ws-composer__words--empty { color: var(--color-text-muted); }
|
|
21
|
+
/* The tools on the right, 2 apart: plus and mic as 36 square tools (a tool that is on turns into the navy round), then
|
|
22
|
+
the one round navy act, Talk or Send. */
|
|
23
|
+
.ws-composer__trail { display: flex; flex-shrink: 0; align-items: center; gap: var(--space-3xs); }
|
|
24
|
+
.ws-composer__trail > .ws-icon-btn { width: var(--ws-composer-line); height: var(--ws-composer-line); color: var(--color-text-heading); }
|
|
25
|
+
.ws-composer__trail > .ws-icon-btn:not(.ws-icon-btn--primary, [aria-pressed="true"]) { border-radius: var(--ws-radius-control); }
|
|
26
|
+
.ws-composer__trail > .ws-icon-btn:is(.ws-icon-btn--primary, [aria-pressed="true"]) { border-radius: var(--radius-full); color: var(--ws-on-act); }
|
|
27
|
+
.ws-composer__trail > .ws-icon-btn svg { width: var(--ws-icon); height: var(--ws-icon); }
|
|
28
|
+
@media (hover: hover) { .ws-composer__trail > .ws-icon-btn:not(.ws-icon-btn--primary, [aria-pressed="true"]):hover { background: var(--ws-hover-strong); } }
|
|
29
|
+
/* Touch: the tools' line is 40, and the words, the lead and the rule centre on it. */
|
|
30
|
+
@media (pointer: coarse) { .ws-composer { --ws-composer-line: var(--ws-touch); } }
|
|
31
|
+
/* Live: what is heard is one line, cut at the end (give it a title). */
|
|
32
|
+
.ws-composer--live .ws-composer__words { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
33
|
+
.ws-composer__dot { margin-right: var(--space-xxs); }
|
|
34
|
+
/* The context tab: what the question is about, riding on the field (padding 6 / 6 / 6 / 12, the field's edge on its
|
|
35
|
+
top and sides only, 4 px top corners, a faint navy tint); the field gives up its top corners. Tabs stack, split by a
|
|
36
|
+
0.5 px line. */
|
|
37
|
+
.ws-composer__context { display: flex; align-items: center; gap: var(--space-xs); padding: var(--space-xxs-plus) var(--space-xxs-plus) var(--space-xxs-plus) var(--space-sm); border-radius: var(--ws-radius-control) var(--ws-radius-control) 0 0; box-shadow: inset 0 var(--ws-hairline) 0 var(--ws-edge-card), inset var(--ws-hairline) 0 0 var(--ws-edge-card), inset calc(var(--ws-hairline) * -1) 0 0 var(--ws-edge-card); background: linear-gradient(var(--ws-hover), var(--ws-hover)) var(--ws-field); font-size: var(--ws-text-control); line-height: var(--ws-leading-control); color: var(--color-text-body); }
|
|
38
|
+
.ws-composer__context > svg { flex-shrink: 0; width: var(--ws-icon); height: var(--ws-icon); color: var(--color-text-heading); }
|
|
39
|
+
.ws-composer__context > span { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
40
|
+
.ws-composer__context + .ws-composer__context { border-radius: 0; box-shadow: inset 0 var(--ws-hairline) 0 var(--ws-edge-slot), inset var(--ws-hairline) 0 0 var(--ws-edge-card), inset calc(var(--ws-hairline) * -1) 0 0 var(--ws-edge-card); }
|
|
41
|
+
.ws-composer__context + .ws-composer { border-top-left-radius: 0; border-top-right-radius: 0; }
|
|
42
|
+
/* The field look, for a pane (Seth's "Ask Grow"): 40 tall, the tray grey, 8 px corners, 12 inside and 10 between its
|
|
43
|
+
parts, a 20 px face, 14 / 20 words and a 16 px send arrow. */
|
|
44
|
+
.ws-composer--field { align-items: center; gap: var(--space-xs-plus); min-height: var(--space-2xl); padding: 0 var(--space-xxs) 0 var(--space-sm); border-radius: var(--ws-radius-card); background: var(--ws-tray); box-shadow: none; }
|
|
45
|
+
.ws-composer--field .ws-composer__words { min-height: 0; padding: var(--space-xs-plus) 0; font-size: var(--ws-text-body); line-height: calc(var(--space-md) + var(--space-xxs)); }
|
|
46
|
+
.ws-composer--field { --ws-composer-line: var(--ws-control-h); }
|
|
47
|
+
.ws-composer--field .ws-composer__trail > .ws-icon-btn { background: none; color: var(--color-text-heading); }
|
|
48
|
+
/* Touch: 40 tall and 16 px words (under 16 iOS zooms the page in when the field takes focus), on the same 20 line. */
|
|
49
|
+
@media (pointer: coarse) { .ws-composer--field { --ws-composer-line: var(--ws-touch); } .ws-composer--field .ws-composer__words { font-size: var(--ws-text-value); } }
|
|
50
|
+
/* The navy ground keeps the field white (--ws-field), so on it the words, the tools, the washes, the edges and the
|
|
51
|
+
focus ring take the field's own navy ink and nothing turns white on white. The pane field sits on the tray, not the
|
|
52
|
+
white, so its words take the ground's heading. */
|
|
53
|
+
[data-theme="dark"][data-ground="navy"] :is(.ws-composer:not(.ws-composer--field), .ws-composer__context) { --color-text-heading: var(--ws-field-ink); --color-text-body: var(--ws-field-ink); --color-text-muted: var(--color-text-placeholder); --ws-on-act: var(--ws-field); --ws-focus-color: var(--ws-field-ink); --ws-hover: color-mix(in srgb, var(--ws-field-ink) 5%, transparent); --ws-hover-strong: color-mix(in srgb, var(--ws-field-ink) 6%, transparent); --ws-edge-card: color-mix(in srgb, var(--ws-field-ink) 18%, transparent); --ws-edge-slot: var(--ws-edge-card); --ws-track: var(--ws-edge-card); --ws-surface-sunk: color-mix(in srgb, var(--ws-field) 92%, var(--ws-field-ink)); --ws-act-hover: color-mix(in srgb, var(--color-text-heading) 92%, var(--ws-on-act)); --ws-edge-hover: var(--color-text-muted); --ws-shadow-hairline-in: inset 0 0 0 var(--ws-hairline) var(--ws-edge-card); }
|
|
54
|
+
[data-theme="dark"][data-ground="navy"] .ws-composer--field { --ws-field-ink: var(--color-text-heading); }
|
|
55
|
+
@media (prefers-color-scheme: dark) {
|
|
56
|
+
[data-theme="system"][data-ground="navy"] :is(.ws-composer:not(.ws-composer--field), .ws-composer__context) { --color-text-heading: var(--ws-field-ink); --color-text-body: var(--ws-field-ink); --color-text-muted: var(--color-text-placeholder); --ws-on-act: var(--ws-field); --ws-focus-color: var(--ws-field-ink); --ws-hover: color-mix(in srgb, var(--ws-field-ink) 5%, transparent); --ws-hover-strong: color-mix(in srgb, var(--ws-field-ink) 6%, transparent); --ws-edge-card: color-mix(in srgb, var(--ws-field-ink) 18%, transparent); --ws-edge-slot: var(--ws-edge-card); --ws-track: var(--ws-edge-card); --ws-surface-sunk: color-mix(in srgb, var(--ws-field) 92%, var(--ws-field-ink)); --ws-act-hover: color-mix(in srgb, var(--color-text-heading) 92%, var(--ws-on-act)); --ws-edge-hover: var(--color-text-muted); --ws-shadow-hairline-in: inset 0 0 0 var(--ws-hairline) var(--ws-edge-card); }
|
|
57
|
+
[data-theme="system"][data-ground="navy"] .ws-composer--field { --ws-field-ink: var(--color-text-heading); }
|
|
58
|
+
}
|
|
59
|
+
/* Focus glow (North's "Focus glow", the glow spring .3 / 0, css:2120): while something in the box has focus, from a
|
|
60
|
+
pointer or a key, a soft drop gathers under it (0 4 16, the shade at 7 %); its edge stays its own and the keyboard
|
|
61
|
+
ring is still the kit's (D8). The pane field, a live call and the chat bar keep their own look. */
|
|
62
|
+
:where(.ws-composer:not(.ws-composer--field, .ws-composer--live)):focus-within { box-shadow: inset 0 0 0 var(--ws-hairline) var(--ws-edge-card), 0 var(--space-xxs) var(--space-md) color-mix(in srgb, var(--ws-shade) 7%, transparent); }
|
|
63
|
+
/* The rolling placeholder (North's "Placeholder roll", the roll spring .45 / .05, js@784180): a few questions in a
|
|
64
|
+
ws-composer__roll laid over the words' first line, the words and the roll sharing one cell (ws-composer__slot). The
|
|
65
|
+
shown one (data-on, moved on every 3.4 s by rollPlaceholder() from the package) rolls up out of 12 px and a 3 px blur;
|
|
66
|
+
the one before it rolls on up 12 px into the blur. The words keep the first question as their real placeholder (what
|
|
67
|
+
a screen reader reads), painted clear; the roll goes once there are words. Without the script, or with reduced motion,
|
|
68
|
+
the first question holds. The main field only: the pane field keeps its plain placeholder. */
|
|
69
|
+
.ws-composer__slot { display: grid; flex: 1; min-width: 0; }
|
|
70
|
+
.ws-composer__slot > * { grid-area: 1 / 1; }
|
|
71
|
+
.ws-composer__slot > .ws-composer__words { width: 100%; }
|
|
72
|
+
.ws-composer__roll { display: grid; align-self: start; min-width: 0; padding: calc((var(--ws-composer-line) - var(--ws-leading-message)) / 2) var(--space-3xs) 0 0; font-size: var(--ws-text-value); line-height: var(--ws-leading-message); color: var(--color-text-muted); pointer-events: none; }
|
|
73
|
+
.ws-composer__roll > * { grid-area: 1 / 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; opacity: 0; visibility: hidden; translate: 0 var(--ws-drop); filter: blur(var(--ws-blur-arrive)); }
|
|
74
|
+
.ws-composer__roll > [data-off] { translate: 0 calc(var(--ws-drop) * -1); }
|
|
75
|
+
.ws-composer__roll > [data-on], .ws-composer__roll:not(:has(> [data-on])) > :first-child { opacity: 1; visibility: visible; translate: none; filter: none; }
|
|
76
|
+
.ws-composer__slot:has(> .ws-composer__roll) > .ws-composer__words::placeholder { color: transparent; }
|
|
77
|
+
.ws-composer__words:not(:placeholder-shown) ~ .ws-composer__roll { display: none; }
|
|
78
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
79
|
+
:where(.ws-composer:not(.ws-composer--field, .ws-composer--live)) { transition: box-shadow var(--ws-spring-glow-duration) var(--ws-spring-glow); }
|
|
80
|
+
.ws-composer__roll > :is([data-on], [data-off]) { transition: opacity var(--ws-spring-roll-duration) var(--ws-spring-roll), translate var(--ws-spring-roll-duration) var(--ws-spring-roll), filter var(--ws-spring-roll-duration) var(--ws-spring-roll), visibility var(--ws-spring-roll-duration) var(--ws-spring-roll); }
|
|
81
|
+
}
|
|
@@ -3,87 +3,108 @@ The `Dialog` recipe for the one moment something cannot be undone: name the thin
|
|
|
3
3
|
## Use it when
|
|
4
4
|
|
|
5
5
|
- An action removes something, or removes someone's access to it, and cannot be reversed.
|
|
6
|
-
- An action affects another person, not just the one pressing the button (removing a teammate, deleting a shared
|
|
7
|
-
|
|
8
|
-
- The cost of getting it wrong is high enough that a plain button press is not enough on its own.
|
|
6
|
+
- An action affects another person, not just the one pressing the button (removing a teammate, deleting a shared draft).
|
|
7
|
+
- Getting it wrong costs enough that a plain button press is not enough on its own.
|
|
9
8
|
|
|
10
9
|
## Not for
|
|
11
10
|
|
|
12
|
-
- Anything reversible:
|
|
13
|
-
|
|
14
|
-
-
|
|
15
|
-
- An error: that is a field message or a `Banner`, not a confirmation.
|
|
11
|
+
- Anything reversible: offer Undo in a `Toast` instead; undo beats confirm.
|
|
12
|
+
- A short blocking task that is not destructive (assigning, naming): use plain `Dialog`.
|
|
13
|
+
- An error: that is a field message or a `Banner`.
|
|
16
14
|
|
|
17
15
|
## Anatomy
|
|
18
16
|
|
|
19
|
-
Built
|
|
20
|
-
|
|
21
|
-
a words-only modifier on the destructive button: it keeps the secondary button's cream shell and fine edge, with its
|
|
22
|
-
words recoloured to `--ws-word-needs` instead of navy.
|
|
17
|
+
Built on `Dialog`: the pane in its tray rim, 12 px corners, 28 px sides, the compact head and the foot band, over the
|
|
18
|
+
35% navy scrim. Its `role` is `alertdialog`.
|
|
23
19
|
|
|
24
|
-
- Title: names the thing and the consequence
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
-
|
|
28
|
-
|
|
20
|
+
- Title: names the thing and the consequence as a question ("Remove Priya Nair from the team?"), 22 / 28.
|
|
21
|
+
- Line: one sentence saying what happens ("Her scores and progress go with her. This cannot be undone."), 14 / 20,
|
|
22
|
+
4 under the title, 20 above the foot. Point `aria-describedby` at it.
|
|
23
|
+
- Close: Dialog's 32 px tray square, centred on the title's first line; it stays top right at any width.
|
|
24
|
+
- Foot: two secondary, large acts in `ws-dialog__acts`, 8 apart, on the right. The first keeps the thing ("Keep her");
|
|
25
|
+
the second is the destructive act ("Remove"), the same cream shell with its words in `--ws-word-needs`
|
|
26
|
+
(`ws-confirm-dialog__destructive`). On a phone they fill the width in equal halves, stacked full width
|
|
27
|
+
(keep on top) where a half would be under 160 or a label would break.
|
|
29
28
|
|
|
30
29
|
## Variants and sizes
|
|
31
30
|
|
|
32
31
|
| Variant | Look |
|
|
33
32
|
| --- | --- |
|
|
34
|
-
| Confirm (centre only) |
|
|
33
|
+
| Confirm (centre only) | The one form. There is no drawer version: a confirm is always a short question in the centre |
|
|
35
34
|
|
|
36
35
|
## States
|
|
37
36
|
|
|
38
|
-
- **Open
|
|
39
|
-
- **Focus
|
|
40
|
-
- **
|
|
41
|
-
- **Pending
|
|
42
|
-
|
|
37
|
+
- **Open**: over its scrim; title, line and both acts visible.
|
|
38
|
+
- **Focus**: trapped inside; Tab moves between the close and the two acts. Focus starts on the act that keeps the thing.
|
|
39
|
+
- **Hover**: the destructive act keeps its needs-you words; only its ground tints.
|
|
40
|
+
- **Pending**: the destructive act shows the working dot and its present-tense verb ("Deleting"), with `aria-busy` and
|
|
41
|
+
`aria-disabled`. It stops answering the pointer (no hover tint, no second press); it stays focusable, so the app
|
|
42
|
+
ignores Enter on it until the work is done.
|
|
43
|
+
- **Closing**: as `Dialog`, it fades and drops 8 px over `--ws-duration-exit`.
|
|
43
44
|
|
|
44
45
|
## Behaviour
|
|
45
46
|
|
|
46
|
-
- Keyboard: Escape closes it and returns focus to what opened it,
|
|
47
|
-
- Pointer: a click on the scrim closes it,
|
|
48
|
-
- Motion:
|
|
49
|
-
|
|
50
|
-
- Reduced motion:
|
|
47
|
+
- Keyboard: Escape closes it and returns focus to what opened it, as `Dialog`. Escape and the close both mean "keep".
|
|
48
|
+
- Pointer: a click on the scrim closes it and keeps the thing (`closedby="any"`), as `Dialog`.
|
|
49
|
+
- Motion: as `Dialog` (it is one): it grows 14 px up out of .98 on the settle spring (`--ws-spring-settle`) as the
|
|
50
|
+
scrim fades in, its head and foot settling in after it; it leaves faster, over `--ws-duration-exit`.
|
|
51
|
+
- Reduced motion: it appears and goes at once.
|
|
52
|
+
- The preview's last stack is live: press Remove Priya Nair.
|
|
51
53
|
|
|
52
54
|
## Content
|
|
53
55
|
|
|
54
|
-
- The title
|
|
55
|
-
- The
|
|
56
|
-
|
|
57
|
-
- The destructive act is a short, plain verb ("Remove," "Delete").
|
|
58
|
-
- No em dashes, sentence case.
|
|
56
|
+
- The title names the specific thing and its consequence, never "Are you sure?".
|
|
57
|
+
- The keep act says what staying means here ("Keep her", "Keep the draft"); "Cancel" is fine when nothing warmer fits.
|
|
58
|
+
- The destructive act is a short, plain verb ("Remove", "Delete"); pending, its present tense ("Deleting").
|
|
59
59
|
|
|
60
60
|
## Props
|
|
61
61
|
|
|
62
62
|
| Name | Type | Meaning |
|
|
63
63
|
| --- | --- | --- |
|
|
64
|
-
| `open` | boolean |
|
|
65
|
-
| `onClose` | `() => void` |
|
|
66
|
-
| `title` | string |
|
|
67
|
-
| `line` | string |
|
|
68
|
-
| `keepLabel` | string |
|
|
69
|
-
| `removeLabel` | string |
|
|
70
|
-
| `onConfirm` | `() => void` |
|
|
71
|
-
| `pending` | boolean |
|
|
64
|
+
| `open` | boolean | Drives whether it is open. |
|
|
65
|
+
| `onClose` | `() => void` | Fires on Escape, the scrim, the close or the keep act. |
|
|
66
|
+
| `title` | string | Names the thing and the consequence. |
|
|
67
|
+
| `line` | string | Says what happens. |
|
|
68
|
+
| `keepLabel` | string | The keep act's words, specific to the case. |
|
|
69
|
+
| `removeLabel` | string | The destructive act's words. |
|
|
70
|
+
| `onConfirm` | `() => void` | Fires when the destructive act is pressed. |
|
|
71
|
+
| `pending` | boolean | Shows the working dot on the destructive act and refuses a second press. |
|
|
72
72
|
|
|
73
73
|
## Rules
|
|
74
74
|
|
|
75
|
-
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
-
|
|
79
|
-
`ConfirmDialog` has no primary button at all: both acts are secondary, and the one that destroys something is marked
|
|
80
|
-
only by its word colour, never by a navy fill, since a destructive act must never read as the screen's one recommended
|
|
81
|
-
action.
|
|
82
|
-
- Never a red fill: the destructive act's shell stays the same cream secondary button as "keep," only its words change
|
|
83
|
-
colour.
|
|
75
|
+
- Confirm only what cannot be undone or affects other people (10-patterns.md, "Confirmation and undo").
|
|
76
|
+
- No navy primary act here: both acts are secondary, and the one that destroys is marked only by its word colour, so a
|
|
77
|
+
destructive act never reads as the screen's one recommended act.
|
|
78
|
+
- Never a red fill.
|
|
84
79
|
|
|
85
80
|
## Source
|
|
86
81
|
|
|
87
|
-
**Derived from**: `Dialog`
|
|
88
|
-
|
|
89
|
-
|
|
82
|
+
**Derived from**: `Dialog` applied to the "Confirmation and undo" pattern; the undo alternative beside it is the kit's
|
|
83
|
+
own `Toast`. **Precedent**: the first product built on the system.
|
|
84
|
+
|
|
85
|
+
## Markup
|
|
86
|
+
|
|
87
|
+
```html
|
|
88
|
+
<dialog class="ws-dialog" role="alertdialog" aria-labelledby="remove-title" aria-describedby="remove-line" closedby="any">
|
|
89
|
+
<header class="ws-head">
|
|
90
|
+
<div>
|
|
91
|
+
<h2 id="remove-title" class="ws-title">Remove Priya Nair from the team?</h2>
|
|
92
|
+
<p id="remove-line" class="ws-body">Her scores and progress go with her. This cannot be undone.</p>
|
|
93
|
+
</div>
|
|
94
|
+
<button type="button" class="ws-icon-btn ws-dialog__close" aria-label="Close">
|
|
95
|
+
<svg viewBox="0 0 16 16" fill="none"><path d="M4 4l8 8M12 4l-8 8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
|
|
96
|
+
</button>
|
|
97
|
+
</header>
|
|
98
|
+
<footer class="ws-band">
|
|
99
|
+
<div class="ws-dialog__acts">
|
|
100
|
+
<button type="button" class="ws-btn ws-btn--secondary ws-btn--lg" autofocus>Keep her</button>
|
|
101
|
+
<button type="button" class="ws-btn ws-btn--secondary ws-btn--lg ws-confirm-dialog__destructive">Remove</button>
|
|
102
|
+
</div>
|
|
103
|
+
</footer>
|
|
104
|
+
</dialog>
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Styles
|
|
108
|
+
|
|
109
|
+
`ConfirmDialog/style.css` holds one rule, the destructive act's words; the rest is `Dialog/style.css`. Both are in
|
|
110
|
+
`bundle.css` and `fello.css`. Tokens only, so it turns dark with the page.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<!-- @dsCard group="Overlays" height=
|
|
1
|
+
<!-- @dsCard group="Overlays" height=450 -->
|
|
2
2
|
<!doctype html>
|
|
3
3
|
<html>
|
|
4
4
|
<head>
|
|
@@ -9,42 +9,86 @@
|
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
|
11
11
|
<div class="ws-stage ws-stage--grey">
|
|
12
|
-
<div class="ws-cluster ws-cluster--start" style="gap: var(--space-xl);">
|
|
13
12
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
13
|
+
<div class="ws-stack" style="width: 440px;">
|
|
14
|
+
<span class="ws-muted">Confirm: names the thing and what happens; no navy act, the destructive one in needs-you words</span>
|
|
15
|
+
<div style="display: grid; place-items: center; padding: var(--space-xl) 0; border-radius: var(--ws-radius-panel); background: linear-gradient(var(--ws-scrim), var(--ws-scrim)), var(--ws-page);">
|
|
16
|
+
<div class="ws-dialog" role="alertdialog" aria-modal="true" aria-labelledby="cd-title" aria-describedby="cd-line" style="max-width: 384px;">
|
|
17
|
+
<header class="ws-head">
|
|
18
|
+
<div>
|
|
19
|
+
<h2 id="cd-title" class="ws-title">Remove Priya Nair from the team?</h2>
|
|
20
|
+
<p id="cd-line" class="ws-body">Her scores and progress go with her. This cannot be undone.</p>
|
|
21
|
+
</div>
|
|
22
|
+
<button type="button" class="ws-icon-btn ws-dialog__close" aria-label="Close">
|
|
23
|
+
<svg viewBox="0 0 16 16" fill="none"><path d="M4 4l8 8M12 4l-8 8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
|
|
24
|
+
</button>
|
|
25
|
+
</header>
|
|
26
|
+
<footer class="ws-band">
|
|
27
|
+
<div class="ws-dialog__acts">
|
|
28
28
|
<button type="button" class="ws-btn ws-btn--secondary ws-btn--lg">Keep her</button>
|
|
29
29
|
<button type="button" class="ws-btn ws-btn--secondary ws-btn--lg ws-confirm-dialog__destructive">Remove</button>
|
|
30
|
-
</
|
|
31
|
-
</
|
|
30
|
+
</div>
|
|
31
|
+
</footer>
|
|
32
32
|
</div>
|
|
33
33
|
</div>
|
|
34
|
+
</div>
|
|
34
35
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
36
|
+
<div class="ws-stack" style="width: 440px;">
|
|
37
|
+
<span class="ws-muted">Pending: the destructive act shows the working dot and takes no second press</span>
|
|
38
|
+
<div style="display: grid; place-items: center; padding: var(--space-xl) 0; border-radius: var(--ws-radius-panel); background: linear-gradient(var(--ws-scrim), var(--ws-scrim)), var(--ws-page);">
|
|
39
|
+
<div class="ws-dialog" role="alertdialog" aria-modal="true" aria-labelledby="cd-title-2" aria-describedby="cd-line-2" style="max-width: 384px;">
|
|
40
|
+
<header class="ws-head">
|
|
41
|
+
<div>
|
|
42
|
+
<h2 id="cd-title-2" class="ws-title">Delete the draft to the Whitfield family?</h2>
|
|
43
|
+
<p id="cd-line-2" class="ws-body">Dana wrote it with you yesterday. Nobody can get it back.</p>
|
|
41
44
|
</div>
|
|
42
|
-
<button type="button" class="ws-
|
|
43
|
-
|
|
45
|
+
<button type="button" class="ws-icon-btn ws-dialog__close" aria-label="Close">
|
|
46
|
+
<svg viewBox="0 0 16 16" fill="none"><path d="M4 4l8 8M12 4l-8 8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
|
|
47
|
+
</button>
|
|
48
|
+
</header>
|
|
49
|
+
<footer class="ws-band">
|
|
50
|
+
<div class="ws-dialog__acts">
|
|
51
|
+
<button type="button" class="ws-btn ws-btn--secondary ws-btn--lg">Keep the draft</button>
|
|
52
|
+
<button type="button" class="ws-btn ws-btn--secondary ws-btn--lg ws-confirm-dialog__destructive" aria-busy="true" aria-disabled="true"><span class="ws-dot ws-working" aria-hidden="true"></span>Deleting</button>
|
|
53
|
+
</div>
|
|
54
|
+
</footer>
|
|
44
55
|
</div>
|
|
45
56
|
</div>
|
|
57
|
+
</div>
|
|
46
58
|
|
|
59
|
+
<div class="ws-stack" style="width: 320px;">
|
|
60
|
+
<span class="ws-muted">Undo beats confirm: the reversible case is a toast with Undo</span>
|
|
61
|
+
<div class="ws-toast" role="status">
|
|
62
|
+
<svg class="ws-toast__icon" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M3.5 8.5l3 3 6-7" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
|
63
|
+
<div class="ws-toast__body">
|
|
64
|
+
<p class="ws-toast__title">Removed Priya Nair from the team</p>
|
|
65
|
+
</div>
|
|
66
|
+
<button type="button" class="ws-toast__action">Undo</button>
|
|
67
|
+
</div>
|
|
68
|
+
</div>
|
|
69
|
+
|
|
70
|
+
<div class="ws-stack" style="width: 320px;" data-live>
|
|
71
|
+
<span class="ws-muted">Live: press Remove. It moves as every Dialog does: up out of .98 on the settle spring, its parts settling in after it; Escape or either act sends it off faster</span>
|
|
72
|
+
<button type="button" class="ws-btn ws-btn--secondary ws-confirm-dialog__destructive" style="align-self: flex-start;" onclick="document.getElementById('cd-live').showModal()">Remove Priya Nair</button>
|
|
73
|
+
<dialog id="cd-live" class="ws-dialog" role="alertdialog" aria-labelledby="cd-live-title" aria-describedby="cd-live-line" closedby="any" style="max-width: 384px;">
|
|
74
|
+
<header class="ws-head">
|
|
75
|
+
<div>
|
|
76
|
+
<h2 id="cd-live-title" class="ws-title">Remove Priya Nair from the team?</h2>
|
|
77
|
+
<p id="cd-live-line" class="ws-body">Her scores and progress go with her. This cannot be undone.</p>
|
|
78
|
+
</div>
|
|
79
|
+
<button type="button" class="ws-icon-btn ws-dialog__close" aria-label="Close" onclick="this.closest('dialog').close()">
|
|
80
|
+
<svg viewBox="0 0 16 16" fill="none"><path d="M4 4l8 8M12 4l-8 8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
|
|
81
|
+
</button>
|
|
82
|
+
</header>
|
|
83
|
+
<footer class="ws-band">
|
|
84
|
+
<div class="ws-dialog__acts">
|
|
85
|
+
<button type="button" class="ws-btn ws-btn--secondary ws-btn--lg" onclick="this.closest('dialog').close()">Keep her</button>
|
|
86
|
+
<button type="button" class="ws-btn ws-btn--secondary ws-btn--lg ws-confirm-dialog__destructive" onclick="this.closest('dialog').close()">Remove</button>
|
|
87
|
+
</div>
|
|
88
|
+
</footer>
|
|
89
|
+
</dialog>
|
|
47
90
|
</div>
|
|
91
|
+
|
|
48
92
|
</div>
|
|
49
93
|
</body>
|
|
50
94
|
</html>
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/* ---- ConfirmDialog: a Dialog that asks before something that cannot be undone; the act in needs-you words ---- */
|
|
2
|
+
/* The words keep their colour on hover and while pending, whatever the secondary button's own hover does. */
|
|
3
|
+
.ws-confirm-dialog__destructive, .ws-confirm-dialog__destructive:hover { color: var(--ws-word-needs); }
|
|
4
|
+
/* Pending (aria-disabled): no hover tint and no second press from a pointer; the app ignores Enter while it is busy. */
|
|
5
|
+
.ws-confirm-dialog__destructive[aria-disabled="true"] { pointer-events: none; }
|
|
@@ -11,11 +11,11 @@
|
|
|
11
11
|
<div class="ws-cover">
|
|
12
12
|
<!--
|
|
13
13
|
blocks: brand-navy 360 x 112 (space-9xl + space-8xl), brand-salmon 240 x 112 (space-9xl + space-2xl), ws-chart-past-half 200 x 112 (space-9xl), ws-chart-finished 160 x 112 (space-8xl); a strip of unequal bands across the top, flush, square (the goal strip's order: navy, then salmon to purple to teal).
|
|
14
|
-
arrangement: the top-band skeleton (the name is wider than 440 px at 64 px), the band 112 px tall, the name a step (space-
|
|
14
|
+
arrangement: the top-band skeleton (the name is wider than 440 px at 64 px), the band 112 px tall at 960 and scaled with the width below it, the name a step (space-xl) under it and flowing, so a phone keeps every tone and reads every word.
|
|
15
15
|
pattern: the goal strip's ticks: "counts out of a whole are tick rows" and "0.5 px edges, 2 px chips" say precise and modular; forty ticks space-xs wide and space-2xl tall at a space-lg pitch, radius-xs corners, in the ground colour cut out of the blocks, rising from the band's foot.
|
|
16
16
|
scales: widths from space-9xl, space-8xl, space-2xl; tick width space-xs, height space-2xl, pitch space-lg, corners radius-xs; the gap under the band space-lg; the text inset space-2xl.
|
|
17
17
|
-->
|
|
18
|
-
<svg class="ws-cover__art" viewBox="0 0 960
|
|
18
|
+
<svg class="ws-cover__art" viewBox="0 0 960 120" aria-hidden="true">
|
|
19
19
|
<rect class="ws-cover__navy" x="0" y="0" width="360" height="112"/>
|
|
20
20
|
<rect class="ws-cover__salmon" x="360" y="0" width="240" height="112"/>
|
|
21
21
|
<rect class="ws-cover__purple" x="600" y="0" width="200" height="112"/>
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
<rect class="ws-cover__tick" x="8" y="64" width="8" height="40"/><rect class="ws-cover__tick" x="32" y="64" width="8" height="40"/><rect class="ws-cover__tick" x="56" y="64" width="8" height="40"/><rect class="ws-cover__tick" x="80" y="64" width="8" height="40"/><rect class="ws-cover__tick" x="104" y="64" width="8" height="40"/><rect class="ws-cover__tick" x="128" y="64" width="8" height="40"/><rect class="ws-cover__tick" x="152" y="64" width="8" height="40"/><rect class="ws-cover__tick" x="176" y="64" width="8" height="40"/><rect class="ws-cover__tick" x="200" y="64" width="8" height="40"/><rect class="ws-cover__tick" x="224" y="64" width="8" height="40"/><rect class="ws-cover__tick" x="248" y="64" width="8" height="40"/><rect class="ws-cover__tick" x="272" y="64" width="8" height="40"/><rect class="ws-cover__tick" x="296" y="64" width="8" height="40"/><rect class="ws-cover__tick" x="320" y="64" width="8" height="40"/><rect class="ws-cover__tick" x="344" y="64" width="8" height="40"/>
|
|
25
25
|
<rect class="ws-cover__tick" x="368" y="64" width="8" height="40"/><rect class="ws-cover__tick" x="392" y="64" width="8" height="40"/><rect class="ws-cover__tick" x="416" y="64" width="8" height="40"/><rect class="ws-cover__tick" x="440" y="64" width="8" height="40"/><rect class="ws-cover__tick" x="464" y="64" width="8" height="40"/><rect class="ws-cover__tick" x="488" y="64" width="8" height="40"/><rect class="ws-cover__tick" x="512" y="64" width="8" height="40"/><rect class="ws-cover__tick" x="536" y="64" width="8" height="40"/><rect class="ws-cover__tick" x="560" y="64" width="8" height="40"/><rect class="ws-cover__tick" x="584" y="64" width="8" height="40"/>
|
|
26
26
|
<rect class="ws-cover__tick" x="608" y="64" width="8" height="40"/><rect class="ws-cover__tick" x="632" y="64" width="8" height="40"/><rect class="ws-cover__tick" x="656" y="64" width="8" height="40"/><rect class="ws-cover__tick" x="680" y="64" width="8" height="40"/><rect class="ws-cover__tick" x="704" y="64" width="8" height="40"/><rect class="ws-cover__tick" x="728" y="64" width="8" height="40"/><rect class="ws-cover__tick" x="752" y="64" width="8" height="40"/><rect class="ws-cover__tick" x="776" y="64" width="8" height="40"/>
|
|
27
|
-
<rect class="ws-cover__tick" x="
|
|
27
|
+
<rect class="ws-cover__tick" x="800" y="64" width="8" height="40"/><rect class="ws-cover__tick" x="824" y="64" width="8" height="40"/><rect class="ws-cover__tick" x="848" y="64" width="8" height="40"/><rect class="ws-cover__tick" x="872" y="64" width="8" height="40"/><rect class="ws-cover__tick" x="896" y="64" width="8" height="40"/><rect class="ws-cover__tick" x="920" y="64" width="8" height="40"/><rect class="ws-cover__tick" x="944" y="64" width="8" height="40"/>
|
|
28
28
|
</g>
|
|
29
29
|
<rect class="ws-cover__tint" x="0" y="112" width="960" height="8"/>
|
|
30
30
|
</svg>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/* ---- Cover: the system's own cover, 960 by 288: the goal strip's four tones cut by ticks, the name a step under it ---- */
|
|
2
|
+
/* The art is a picture: it scales with the cover's width (the band is the SVG's whole viewBox), so a phone sees all four
|
|
3
|
+
tones. The words flow under it at their own sizes instead of being pinned to 960 px coordinates. */
|
|
4
|
+
.ws-cover { max-width: calc(var(--space-9xl) * 4 + var(--space-8xl)); padding-bottom: var(--space-sm); background: var(--color-bg-page); }
|
|
5
|
+
.ws-cover__art { display: block; width: 100%; height: auto; }
|
|
6
|
+
.ws-cover__navy { fill: var(--color-brand-navy); }
|
|
7
|
+
.ws-cover__salmon { fill: var(--color-brand-salmon); }
|
|
8
|
+
.ws-cover__purple { fill: var(--ws-chart-past-half); }
|
|
9
|
+
.ws-cover__teal { fill: var(--ws-chart-finished); }
|
|
10
|
+
.ws-cover__tint { fill: var(--ws-surface-sunk); }
|
|
11
|
+
.ws-cover__ground { fill: var(--color-bg-page); }
|
|
12
|
+
.ws-cover__tick { rx: var(--ws-radius-chip); }
|
|
13
|
+
.ws-cover__name { margin: var(--space-xl) var(--space-2xl) 0; font-size: var(--font-size-6xl); line-height: 0.95; font-weight: 600; letter-spacing: var(--ws-tracking-title); color: var(--color-text-heading); text-wrap: balance; }
|
|
14
|
+
.ws-cover__line { margin: var(--space-lg) var(--space-2xl) 0; max-width: var(--ws-thing-width); font-size: var(--ws-text-body); line-height: calc(var(--space-md) + var(--space-xxs)); color: var(--color-text-muted); }
|
|
15
|
+
/* A phone: the 16 px margin and the name a step down (64 to 40), as Hero does. */
|
|
16
|
+
@media (max-width: 40rem) {
|
|
17
|
+
.ws-cover__name { margin: var(--space-lg) var(--space-md) 0; font-size: var(--font-size-3xl); line-height: var(--space-3xl); }
|
|
18
|
+
.ws-cover__line { margin: var(--space-xs) var(--space-md) 0; }
|
|
19
|
+
}
|
|
@@ -14,8 +14,8 @@ A date field that works on its own, with a popover month grid for picking a day
|
|
|
14
14
|
|
|
15
15
|
## Anatomy
|
|
16
16
|
|
|
17
|
-
- Field: `Input`'s exact shell (32 px, `--ws-radius-control`, white `--ws-field`,
|
|
18
|
-
|
|
17
|
+
- Field: `Input`'s exact shell (32 px, `--ws-radius-control`, white `--ws-field`, the inside edge, the kit's focus
|
|
18
|
+
ring), a native `<input type="date">`, with a 16 px navy calendar line icon at the right, decorative,
|
|
19
19
|
positioned the way `Select`'s own chevron sits.
|
|
20
20
|
- Picker: a `ws-menu` card (cream, `--ws-radius-card`, `--ws-shadow-lift`) holding a month grid.
|
|
21
21
|
- Header: 32 px row (`--ws-control-h`), the month name 14 px medium navy, two `xs` ghost `IconButton`s (24 px) at the
|
|
@@ -24,12 +24,19 @@ A date field that works on its own, with a popover month grid for picking a day
|
|
|
24
24
|
- Day cells: 32 px (`--ws-control-h`), `--ws-radius-control` (4 px) corners. This is a squarer cell than
|
|
25
25
|
`StreakCalendar`'s pill-shaped day cells, because a picker is a month grid for choosing one day, not a strip
|
|
26
26
|
showing a history of days; the two share colour and letter conventions, not cell shape.
|
|
27
|
-
- Today: a
|
|
28
|
-
|
|
29
|
-
- Chosen day: solid `--color-text-heading` fill,
|
|
30
|
-
|
|
27
|
+
- Today: a 1 px ring in the salmon's AA step (`--ws-word-needs`; the salmon at 0.5 px was 2.6:1, under the 3:1 a
|
|
28
|
+
mark asks), navy numeral.
|
|
29
|
+
- Chosen day: solid `--color-text-heading` fill, `--ws-on-act` numeral, the same `--ws-radius-control` corners;
|
|
30
|
+
`aria-pressed="true"` (today carries `aria-current="date"`).
|
|
31
|
+
- Range: `--ws-surface-sunk` fill across the cells between two navy, chosen end days; days abut across a row (2 px
|
|
32
|
+
between weeks), so a range reads as one band.
|
|
33
|
+
- Numerals: 13 / 18, even.
|
|
34
|
+
- On touch the grid fills its column (up to 320) and loses its insets, so a day is 40 tall and, from a 280 px column,
|
|
35
|
+
40 wide; the header is 40 tall and its month buttons are 40 px boxes on the outer days' edges, so their target
|
|
36
|
+
never spills out of the picker (it never drags sideways).
|
|
31
37
|
- Outside the month: muted numerals, no fill.
|
|
32
|
-
- Past-disabled: 40% opacity, matching `Button`'s and `IconButton`'s own disabled value
|
|
38
|
+
- Past-disabled: 40% opacity, matching `Button`'s and `IconButton`'s own disabled value, and `aria-disabled="true"`
|
|
39
|
+
so a screen reader says it cannot be chosen.
|
|
33
40
|
|
|
34
41
|
## Variants and sizes
|
|
35
42
|
|
|
@@ -45,8 +52,12 @@ There is one size; the field expands to 40 px on a touch screen, where the platf
|
|
|
45
52
|
- **Field alone:** the native input and its calendar icon, no picker open.
|
|
46
53
|
- **Open picker:** the month grid, including today's ring, a muted out-of-month day and a past-disabled day.
|
|
47
54
|
- **A range:** two navy ends with the sunk fill between them.
|
|
48
|
-
- **Focus:** the
|
|
49
|
-
- **Error:** the
|
|
55
|
+
- **Focus:** the kit's focus ring, 2 px navy, 2 px out, as `Input`'s (a field's edge darkens under the pointer).
|
|
56
|
+
- **Error:** the salmon's AA step as a 1 px edge with a message below, exactly as `Input`'s error state.
|
|
57
|
+
- **Hover (a mouse only):** a day takes the navy wash.
|
|
58
|
+
- **Day focus:** the kit's ring drawn inside the day (the grid is dense); on a navy day the ring is the numeral's colour,
|
|
59
|
+
2 px further in, so it never vanishes into the fill.
|
|
60
|
+
- **Dark:** the menu, the days and the act take their dark values.
|
|
50
61
|
- **Disabled:** the field is not editable, the icon and picker are inert.
|
|
51
62
|
|
|
52
63
|
## Behaviour
|
|
@@ -56,7 +67,7 @@ There is one size; the field expands to 40 px on a touch screen, where the platf
|
|
|
56
67
|
the active cell, Escape closes the picker and returns focus to the field, and the header's buttons (or Page Up/Down)
|
|
57
68
|
move months.
|
|
58
69
|
- Pointer / touch: clicking a day cell chooses it; the field's own calendar icon opens the picker.
|
|
59
|
-
- Motion: the picker opens
|
|
70
|
+
- Motion: the picker opens as `Menu` does, growing from its top left corner, under the field's left edge (D7).
|
|
60
71
|
- Reduced motion: the picker appears without its rise.
|
|
61
72
|
|
|
62
73
|
## Content
|
|
@@ -81,8 +92,8 @@ There is one size; the field expands to 40 px on a touch screen, where the platf
|
|
|
81
92
|
- 08-choosing-components.md previously read: "Pick a date or a time | a native input until a picker is built | listed
|
|
82
93
|
as later." This is that picker arriving (26 Oct 2026): the native field stays the whole story on its own, and the
|
|
83
94
|
picker is an enhancement, never a replacement.
|
|
84
|
-
- Today
|
|
85
|
-
|
|
95
|
+
- Today is an outline in the salmon's AA step, nothing else about the cell changes; the muted day-letter row comes from
|
|
96
|
+
`StreakCalendar`; the cell shape does not, since the two components solve different problems.
|
|
86
97
|
- 40% opacity for a past-disabled day matches `Button`'s and `IconButton`'s own disabled value, not `Checkbox`'s 50%.
|
|
87
98
|
|
|
88
99
|
## Source
|
|
@@ -90,3 +101,57 @@ There is one size; the field expands to 40 px on a touch screen, where the platf
|
|
|
90
101
|
**Derived from**: `Input`'s field chrome, `Select`'s chevron-positioning pattern, `StreakCalendar`'s today-marking
|
|
91
102
|
colour and day-letter conventions, and `Menu`'s `ws-menu` panel shell and motion. **Precedent**: an intentional
|
|
92
103
|
addition decided from the system, 26 Oct 2026 (filling the "listed as later" line in 08-choosing-components.md).
|
|
104
|
+
|
|
105
|
+
## Markup
|
|
106
|
+
|
|
107
|
+
```html
|
|
108
|
+
<label class="ws-field">
|
|
109
|
+
<span class="ws-label">Call date</span>
|
|
110
|
+
<span class="ws-date-input">
|
|
111
|
+
<input class="ws-input" type="date" value="2026-10-22">
|
|
112
|
+
<svg class="ws-date-input__icon" 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.5" y="3.5" width="11" height="10" rx="1.5"/><path d="M2.5 6.5h11M5 2v3M11 2v3"/></svg>
|
|
113
|
+
</span>
|
|
114
|
+
</label>
|
|
115
|
+
<div class="ws-menu ws-date-input__picker" role="dialog" aria-label="Choose a date">
|
|
116
|
+
<div class="ws-date-input__head">
|
|
117
|
+
<button type="button" class="ws-icon-btn ws-icon-btn--xs" aria-label="Previous month">...</button>
|
|
118
|
+
<span class="ws-date-input__month">October 2026</span>
|
|
119
|
+
<button type="button" class="ws-icon-btn ws-icon-btn--xs" aria-label="Next month">...</button>
|
|
120
|
+
</div>
|
|
121
|
+
<div class="ws-date-input__grid">
|
|
122
|
+
<span class="ws-date-input__letter">M</span> ...
|
|
123
|
+
<!-- outside the month, and a day that cannot be chosen (past or out of range) -->
|
|
124
|
+
<button type="button" class="ws-date-input__cell ws-date-input__cell--muted ws-date-input__cell--disabled" aria-disabled="true">30</button>
|
|
125
|
+
<button type="button" class="ws-date-input__cell ws-date-input__cell--disabled" aria-disabled="true">1</button>
|
|
126
|
+
...
|
|
127
|
+
<button type="button" class="ws-date-input__cell ws-date-input__cell--chosen" aria-pressed="true">22</button>
|
|
128
|
+
<button type="button" class="ws-date-input__cell ws-date-input__cell--today" aria-current="date">26</button>
|
|
129
|
+
<button type="button" class="ws-date-input__cell ws-date-input__cell--muted">1</button>
|
|
130
|
+
</div>
|
|
131
|
+
</div>
|
|
132
|
+
|
|
133
|
+
<!-- a range: two navy ends, the sunk band between them -->
|
|
134
|
+
<div class="ws-date-input__grid">
|
|
135
|
+
...
|
|
136
|
+
<button type="button" class="ws-date-input__cell ws-date-input__cell--range-start" aria-pressed="true">12</button>
|
|
137
|
+
<button type="button" class="ws-date-input__cell ws-date-input__cell--range">13</button>
|
|
138
|
+
<button type="button" class="ws-date-input__cell ws-date-input__cell--range">14</button>
|
|
139
|
+
<button type="button" class="ws-date-input__cell ws-date-input__cell--range-end" aria-pressed="true">15</button>
|
|
140
|
+
...
|
|
141
|
+
</div>
|
|
142
|
+
|
|
143
|
+
<!-- the field in error -->
|
|
144
|
+
<div class="ws-field">
|
|
145
|
+
<label class="ws-label" for="close">Close date</label>
|
|
146
|
+
<span class="ws-date-input">
|
|
147
|
+
<input class="ws-input" id="close" type="date" aria-invalid="true" aria-describedby="close-msg">
|
|
148
|
+
<svg class="ws-date-input__icon" 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.5" y="3.5" width="11" height="10" rx="1.5"/><path d="M2.5 6.5h11M5 2v3M11 2v3"/></svg>
|
|
149
|
+
</span>
|
|
150
|
+
<p class="ws-field-msg ws-field-msg--error" id="close-msg">Pick a day after the offer was sent</p>
|
|
151
|
+
</div>
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## Styles
|
|
155
|
+
|
|
156
|
+
`design-system/components/DateInput/style.css`: `ws-date-input`, `__icon`, `__picker`, `__head`, `__month`, `__grid`,
|
|
157
|
+
`__letter`, `__cell` and its `--muted`, `--today`, `--chosen`, `--disabled`, `--range`, `--range-start`, `--range-end`.
|