@openwarelabs/ui 0.2.0 → 0.3.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/README.md CHANGED
@@ -50,17 +50,19 @@ import { Button, Field, Input, Toaster, toast } from "@openwarelabs/ui";
50
50
 
51
51
  ## Components
52
52
 
53
- 70 components, each with a page in the docs.
53
+ 71 components, each with a page in the docs.
54
54
 
55
55
  | Group | Components |
56
56
  | --- | --- |
57
- | Buttons | `Button` (primary, secondary, ghost, danger; sm, md, lg; `loading`; `shape="pill"`), `buttonClassName()` for links, `ButtonGroup`, `ToggleButton`, `CloseButton`, `CopyButton`, `SegmentedControl`, `ChoiceCard` |
58
- | Forms | `Field`, `Fieldset`, `Input` (start and end content), `SearchField`, `NumberField`, `InputOTP`, `Textarea` (`autoGrow`), `Select`, `Combobox`, `Checkbox`, `CheckboxGroup`, `RadioGroup` (plain or cards), `Switch`, `Slider` (one value or a range), `ColorPicker`, `ColorField`, `FileDropZone` |
59
- | Dates | `Calendar`, `DatePicker` |
57
+ | Typography | `Text` (each style on the Typography page as a variant: hero to caption, code and kbd; tones, `truncate`, `as`), `Link`, `Kbd`, `Code`, `CodeBlock`, `Snippet` |
58
+ | Actions | `Button` (primary, secondary, ghost, danger; sm, md, lg; `loading`; `shape="pill"`), `buttonClassName()` for links, `ButtonGroup`, `CloseButton`, `CopyButton`, `ToggleButton`, `SegmentedControl` |
59
+ | Inputs | `Field`, `Fieldset`, `Input` (start and end content), `Textarea` (`autoGrow`), `NumberField`, `SearchField`, `InputOTP`, `ColorField` |
60
+ | Choices | `Checkbox`, `CheckboxGroup`, `RadioGroup` (plain or cards), `Switch`, `Select`, `Combobox`, `Slider` (one value or a range), `ChoiceCard` |
61
+ | Pickers | `Calendar`, `DatePicker`, `ColorPicker`, `FileDropZone` |
60
62
  | Feedback | `Alert`, `Badge`, `ProgressBar`, `ProgressCircle`, `Spinner`, `Skeleton`, `SkeletonRows`, `Toaster` + `toast()` (sonner: stacked, swipeable, with actions and promises), `Tooltip` |
61
63
  | Overlays | `Dialog`, `ConfirmDialog`, `Drawer`, `Popover`, `Menu` + `MenuItem`, `CommandPalette` |
62
- | Navigation | `Tabs`, `Accordion`, `Disclosure`, `Breadcrumbs`, `Link`, `Pagination`, `Steps`, `NavList` + `NavItem` |
63
- | Data display | `Table` (sorting, selection), `Stat`, `FileTree`, `EmptyState`, `Tag`, `ColorSwatch`, `Avatar`, `AvatarGroup`, `User`, `Kbd`, `Code`, `CodeBlock`, `Snippet` |
64
+ | Navigation | `Tabs`, `Accordion`, `Disclosure`, `Breadcrumbs`, `Pagination`, `Steps`, `NavList` + `NavItem` |
65
+ | Data display | `Table` (sorting, selection), `Stat`, `FileTree`, `EmptyState`, `Tag`, `ColorSwatch`, `Avatar`, `AvatarGroup`, `User` |
64
66
  | Layout | `Card`, `SettingsRow`, `Stack`, `Separator`, `ScrollShadow`, `VisuallyHidden` |
65
67
  | Marketing | `SiteHeader`, `SectionHeading`, `Chip`, `DotGrid` |
66
68
 
@@ -0,0 +1,26 @@
1
+ import type { HTMLAttributes, JSX, ReactNode } from "react";
2
+ /** The text styles on the Typography page, by the same names: `lead` is the class ow-type-lead. */
3
+ export type TextVariant = "hero" | "page-title" | "section-title" | "heading" | "lead" | "prose" | "dialog-title" | "card-title" | "body" | "copy" | "label" | "button" | "caption" | "badge" | "overline" | "code" | "kbd";
4
+ export type TextTone = "default" | "soft" | "muted" | "primary" | "danger" | "success" | "warning";
5
+ export interface TextProps extends HTMLAttributes<HTMLElement> {
6
+ /** Which text style: size, leading, weight and tracking from the Typography page. The display styles shrink on phones.
7
+ * @default "body" */
8
+ variant?: TextVariant;
9
+ /** The element, for the page's outline. Defaults to one that suits the variant: h1 for hero and page-title, h2 for
10
+ * section-title, h3 for heading and the titles, p for running text, span for the rest. */
11
+ as?: keyof JSX.IntrinsicElements;
12
+ /** The colour. Left out, lead, copy, caption and overline are muted, as the styles ask, and the rest take the
13
+ * colour around them. */
14
+ tone?: TextTone;
15
+ /** @default "start" */
16
+ align?: "start" | "center" | "end";
17
+ /** One line, cut off with an ellipsis.
18
+ * @default false */
19
+ truncate?: boolean;
20
+ children?: ReactNode;
21
+ }
22
+ /**
23
+ * Text in one of Openware's styles: `<Text variant="lead">`. The variant sets the look and a sensible element;
24
+ * `as` changes the element without changing the look, so the outline stays right.
25
+ */
26
+ export declare function Text({ variant, as, tone, align, truncate, className, children, ...props }: TextProps): JSX.Element;
@@ -0,0 +1,26 @@
1
+ import type { HTMLAttributes, JSX, ReactNode } from "react";
2
+ /** The text styles on the Typography page, by the same names: `lead` is the class ow-type-lead. */
3
+ export type TextVariant = "hero" | "page-title" | "section-title" | "heading" | "lead" | "prose" | "dialog-title" | "card-title" | "body" | "copy" | "label" | "button" | "caption" | "badge" | "overline" | "code" | "kbd";
4
+ export type TextTone = "default" | "soft" | "muted" | "primary" | "danger" | "success" | "warning";
5
+ export interface TextProps extends HTMLAttributes<HTMLElement> {
6
+ /** Which text style: size, leading, weight and tracking from the Typography page. The display styles shrink on phones.
7
+ * @default "body" */
8
+ variant?: TextVariant;
9
+ /** The element, for the page's outline. Defaults to one that suits the variant: h1 for hero and page-title, h2 for
10
+ * section-title, h3 for heading and the titles, p for running text, span for the rest. */
11
+ as?: keyof JSX.IntrinsicElements;
12
+ /** The colour. Left out, lead, copy, caption and overline are muted, as the styles ask, and the rest take the
13
+ * colour around them. */
14
+ tone?: TextTone;
15
+ /** @default "start" */
16
+ align?: "start" | "center" | "end";
17
+ /** One line, cut off with an ellipsis.
18
+ * @default false */
19
+ truncate?: boolean;
20
+ children?: ReactNode;
21
+ }
22
+ /**
23
+ * Text in one of Openware's styles: `<Text variant="lead">`. The variant sets the look and a sensible element;
24
+ * `as` changes the element without changing the look, so the outline stays right.
25
+ */
26
+ export declare function Text({ variant, as, tone, align, truncate, className, children, ...props }: TextProps): JSX.Element;
@@ -105,6 +105,104 @@
105
105
  }
106
106
  }
107
107
 
108
+ /* components/Text/Text.css */
109
+ /* Text: the type styles from tokens.css as a component, with colours and the sizes the display styles take on phones. */
110
+ .ow-text {
111
+ margin: 0;
112
+ }
113
+
114
+ /* Titles balance their lines; running text avoids a lone last word. */
115
+ .ow-text--hero,
116
+ .ow-text--page-title,
117
+ .ow-text--section-title,
118
+ .ow-text--heading {
119
+ text-wrap: balance;
120
+ }
121
+
122
+ .ow-text--lead,
123
+ .ow-text--prose,
124
+ .ow-text--copy {
125
+ text-wrap: pretty;
126
+ }
127
+
128
+ .ow-text--lead {
129
+ max-width: 560px;
130
+ }
131
+
132
+ .ow-text--overline {
133
+ text-transform: uppercase;
134
+ }
135
+
136
+ .ow-text--code,
137
+ .ow-text--kbd {
138
+ font-variant-ligatures: none;
139
+ }
140
+
141
+ .ow-text--default {
142
+ color: var(--ow-text);
143
+ }
144
+
145
+ .ow-text--soft {
146
+ color: var(--ow-text-soft);
147
+ }
148
+
149
+ .ow-text--muted {
150
+ color: var(--ow-text-muted);
151
+ }
152
+
153
+ .ow-text--primary {
154
+ color: var(--ow-primary-text);
155
+ }
156
+
157
+ .ow-text--danger {
158
+ color: var(--ow-danger-text);
159
+ }
160
+
161
+ .ow-text--success {
162
+ color: var(--ow-success-text);
163
+ }
164
+
165
+ .ow-text--warning {
166
+ color: var(--ow-warning-text);
167
+ }
168
+
169
+ .ow-text--center {
170
+ text-align: center;
171
+ }
172
+
173
+ .ow-text--center.ow-text--lead {
174
+ margin-inline: auto;
175
+ }
176
+
177
+ .ow-text--end {
178
+ text-align: end;
179
+ }
180
+
181
+ .ow-text--truncate {
182
+ overflow: hidden;
183
+ text-overflow: ellipsis;
184
+ white-space: nowrap;
185
+ }
186
+
187
+ /* The display styles on phones, as the Typography page gives them. */
188
+ @media (max-width: 760px) {
189
+ .ow-text--hero {
190
+ font-size: 42px;
191
+ line-height: 1.02;
192
+ }
193
+ .ow-text--page-title {
194
+ font-size: 40px;
195
+ line-height: 1.06;
196
+ }
197
+ .ow-text--section-title {
198
+ font-size: 32px;
199
+ line-height: 1.12;
200
+ }
201
+ .ow-text--heading {
202
+ font-size: 21px;
203
+ }
204
+ }
205
+
108
206
  /* components/Spinner/Spinner.css */
109
207
  /* Spinner: a ring with one coloured quarter, turning. */
110
208
  .ow-spinner {
@@ -1048,19 +1146,22 @@
1048
1146
 
1049
1147
  .ow-option {
1050
1148
  display: flex;
1051
- min-height: 32px;
1149
+ min-height: 36px;
1052
1150
  align-items: flex-start;
1053
1151
  gap: var(--ow-space-sm);
1054
1152
  border-radius: var(--ow-radius-lg);
1055
- padding: var(--ow-space-xs) var(--ow-space-sm);
1153
+ /* 10 + a 16px line + 10: one line sits centred in the 36px row; a description just makes the row taller. */
1154
+ padding: var(--ow-space-md);
1056
1155
  color: var(--ow-text);
1057
1156
  font-size: 14px;
1058
- line-height: 1.1;
1157
+ line-height: 16px;
1059
1158
  text-align: left;
1060
1159
  cursor: pointer;
1061
1160
  }
1062
1161
 
1063
1162
  .ow-listbox--sm .ow-option {
1163
+ min-height: 32px;
1164
+ padding-block: var(--ow-space-sm);
1064
1165
  font-size: 12px;
1065
1166
  }
1066
1167
 
@@ -1081,11 +1182,11 @@
1081
1182
  .ow-option__check {
1082
1183
  display: flex;
1083
1184
  width: 16px;
1185
+ /* As tall as the label's first line, so the tick sits level with it. */
1084
1186
  height: 16px;
1085
1187
  flex-shrink: 0;
1086
1188
  align-items: center;
1087
1189
  justify-content: center;
1088
- padding-top: 2px;
1089
1190
  color: var(--ow-primary-text);
1090
1191
  }
1091
1192
 
@@ -1093,7 +1194,7 @@
1093
1194
  display: grid;
1094
1195
  min-width: 0;
1095
1196
  flex: 1;
1096
- gap: var(--ow-space-3xs);
1197
+ gap: var(--ow-space-2xs);
1097
1198
  }
1098
1199
 
1099
1200
  .ow-option__label {
@@ -1269,12 +1370,13 @@
1269
1370
  cursor: pointer;
1270
1371
  }
1271
1372
 
1373
+ /* Centred on the label's first line, whatever its line height. */
1272
1374
  .ow-check-label .ow-checkbox--md {
1273
- margin-top: 2px;
1375
+ margin-top: calc((1lh - 16px) / 2);
1274
1376
  }
1275
1377
 
1276
1378
  .ow-check-label .ow-checkbox--sm {
1277
- margin-top: 3px;
1379
+ margin-top: calc((1lh - 14px) / 2);
1278
1380
  }
1279
1381
 
1280
1382
  .ow-check-label--disabled {
@@ -1284,7 +1386,7 @@
1284
1386
 
1285
1387
  .ow-check-label__text {
1286
1388
  display: grid;
1287
- gap: var(--ow-space-3xs);
1389
+ gap: var(--ow-space-2xs);
1288
1390
  }
1289
1391
 
1290
1392
  .ow-check-label__description {
@@ -2214,7 +2316,7 @@
2214
2316
  border: 0;
2215
2317
  border-radius: var(--ow-radius-md);
2216
2318
  background: var(--ow-tooltip);
2217
- padding: var(--ow-space-3xs) var(--ow-space-sm);
2319
+ padding: var(--ow-space-2xs) var(--ow-space-sm);
2218
2320
  color: var(--ow-on-tooltip);
2219
2321
  font-family: var(--ow-font-sans);
2220
2322
  font-size: 12px;
@@ -2672,7 +2774,7 @@
2672
2774
  display: grid;
2673
2775
  min-width: 0;
2674
2776
  flex: 1;
2675
- gap: var(--ow-space-3xs);
2777
+ gap: var(--ow-space-2xs);
2676
2778
  padding-top: 5px;
2677
2779
  }
2678
2780
 
@@ -3197,7 +3299,7 @@
3197
3299
  }
3198
3300
 
3199
3301
  .ow-palette__group {
3200
- padding: var(--ow-space-sm) var(--ow-space-sm) var(--ow-space-3xs);
3302
+ padding: var(--ow-space-sm) var(--ow-space-sm) var(--ow-space-2xs);
3201
3303
  color: var(--ow-text-muted);
3202
3304
  font-size: 11px;
3203
3305
  font-weight: var(--ow-weight-control);
@@ -3456,7 +3558,7 @@
3456
3558
  .ow-disclosure__titles {
3457
3559
  display: grid;
3458
3560
  min-width: 0;
3459
- gap: var(--ow-space-3xs);
3561
+ gap: var(--ow-space-2xs);
3460
3562
  }
3461
3563
 
3462
3564
  .ow-disclosure__title {
@@ -3801,7 +3903,7 @@
3801
3903
  display: grid;
3802
3904
  min-width: 0;
3803
3905
  flex: 1 1 160px;
3804
- gap: var(--ow-space-3xs);
3906
+ gap: var(--ow-space-2xs);
3805
3907
  }
3806
3908
 
3807
3909
  .ow-steps__title {
@@ -3950,7 +4052,7 @@
3950
4052
 
3951
4053
  .ow-choice__text {
3952
4054
  display: grid;
3953
- gap: var(--ow-space-3xs);
4055
+ gap: var(--ow-space-2xs);
3954
4056
  }
3955
4057
 
3956
4058
  .ow-choice__title {
@@ -4911,7 +5013,7 @@
4911
5013
  display: grid;
4912
5014
  min-width: 0;
4913
5015
  flex: 1 1 192px;
4914
- gap: var(--ow-space-3xs);
5016
+ gap: var(--ow-space-2xs);
4915
5017
  }
4916
5018
 
4917
5019
  .ow-settings-row__label {