@godxjp/ui 27.10.0 → 27.11.0

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.
@@ -11,6 +11,23 @@ type ToggleGroupBaseProp = Omit<React.ComponentPropsWithoutRef<"div">, "defaultV
11
11
  disabled?: boolean;
12
12
  /** Which way the arrow keys walk the group. */
13
13
  orientation?: "horizontal" | "vertical";
14
+ /**
15
+ * Let the row break onto further lines instead of running past its rail (gh#741). Same name,
16
+ * same boolean shape and same `data-wrap` attribute as `Flex` — one spelling answers "what does
17
+ * this row do when it does not fit" across the library.
18
+ *
19
+ * OPT-IN (`false`), and deliberately the SAME default for every `variant`. `Flex`'s `wrap` is
20
+ * `false`, and one word must not mean two defaults. Measured in Chromium at a 320px rail:
21
+ * forcing `flex-wrap: wrap` on all 18 groups of the docs page left the 17 that FIT untouched
22
+ * (same line count, same height, at a 320px and a 1358px rail) — including every `soft` one, so
23
+ * paint is not the axis that decides. The only row it moves is the one that overflows, from
24
+ * 171.5px to 108px: a default of `true` reflows exactly those rows, silently, on an upgrade
25
+ * whose call sites did not change.
26
+ *
27
+ * Wrapping keeps the group's single `gap`, so the two axes stay equal (4px × 4px measured);
28
+ * `flex-wrap` reorders nothing, so arrow keys still walk the items in DOM order across lines.
29
+ */
30
+ wrap?: boolean;
14
31
  /**
15
32
  * Writing direction. It still lands on the DOM node, but React Aria reads the direction it
16
33
  * navigates by from the ambient locale (`I18nProvider`), NOT from this attribute — where Radix
@@ -32,6 +32,7 @@ const ToggleGroup = React.forwardRef(
32
32
  variant,
33
33
  size,
34
34
  shape,
35
+ wrap,
35
36
  children,
36
37
  type,
37
38
  value,
@@ -60,6 +61,7 @@ const ToggleGroup = React.forwardRef(
60
61
  "data-variant": variant,
61
62
  "data-size": size,
62
63
  "data-shape": shape,
64
+ "data-wrap": wrap ? "true" : void 0,
63
65
  className: cn("ui-toggle-group", className),
64
66
  ...props,
65
67
  selectionMode: type,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$comment": "AUTO-GENERATED by scripts/gen-measurement-contract.mjs — do not edit. Read this instead of guessing: docs/MEASUREMENT-CONTRACT.md.",
3
- "version": "27.10.0",
3
+ "version": "27.11.0",
4
4
  "targetSize": {
5
5
  "standard": "WCAG 2.2 SC 2.5.8 Target Size (Minimum), level AA — 24×24 CSS px",
6
6
  "min": 24,
@@ -2464,6 +2464,15 @@ export declare const COMPONENT_PROP_REGISTRY: {
2464
2464
  readonly reason: "Localized unit folded into the accessible name so a counted icon/emoji chip never announces as a bare number.";
2465
2465
  }];
2466
2466
  };
2467
+ readonly ToggleGroupProp: {
2468
+ readonly group: "data-entry";
2469
+ readonly file: "components/ui/toggle-group.tsx";
2470
+ readonly vocabulary: readonly ["ValueProp", "DefaultValueProp", "OnValueChangeProp", "DisabledProp", "SizeProp", "ShapeProp", "ClassNameProp", {
2471
+ readonly field: "wrap";
2472
+ readonly local: true;
2473
+ readonly reason: "The SAME boolean shorthand for flex-wrap that FlexProp carries, on the row that owns a chip set — one spelling for 'what does this row do when it does not fit' (gh#741). Opt-in, and the same default for every variant: paint must not decide geometry.";
2474
+ }];
2475
+ };
2467
2476
  readonly ToggleGroupItemProp: {
2468
2477
  readonly group: "data-entry";
2469
2478
  readonly file: "components/ui/toggle-group.tsx";
@@ -2863,6 +2863,24 @@ const COMPONENT_PROP_REGISTRY = {
2863
2863
  }
2864
2864
  ]
2865
2865
  },
2866
+ ToggleGroupProp: {
2867
+ group: "data-entry",
2868
+ file: "components/ui/toggle-group.tsx",
2869
+ vocabulary: [
2870
+ "ValueProp",
2871
+ "DefaultValueProp",
2872
+ "OnValueChangeProp",
2873
+ "DisabledProp",
2874
+ "SizeProp",
2875
+ "ShapeProp",
2876
+ "ClassNameProp",
2877
+ {
2878
+ field: "wrap",
2879
+ local: true,
2880
+ reason: "The SAME boolean shorthand for flex-wrap that FlexProp carries, on the row that owns a chip set \u2014 one spelling for 'what does this row do when it does not fit' (gh#741). Opt-in, and the same default for every variant: paint must not decide geometry."
2881
+ }
2882
+ ]
2883
+ },
2866
2884
  ToggleGroupItemProp: {
2867
2885
  group: "data-entry",
2868
2886
  file: "components/ui/toggle-group.tsx",
@@ -78,9 +78,14 @@
78
78
  .ui-toggle-group {
79
79
  display: inline-flex;
80
80
  align-items: center;
81
+
81
82
  gap: var(--space-1);
82
83
  }
83
84
 
85
+ .ui-toggle-group[data-wrap="true"] {
86
+ flex-wrap: wrap;
87
+ }
88
+
84
89
  .ui-button {
85
90
  display: inline-flex;
86
91
  align-items: center;
@@ -5,6 +5,22 @@ import { FormField, ToggleGroup, ToggleGroupItem } from "@godxjp/ui/data-entry";
5
5
  import { Text } from "@godxjp/ui/general";
6
6
  import { Flex, PageContainer } from "@godxjp/ui/layout";
7
7
 
8
+ /** A folder's tag facets — more chips than any rail is wide, which is the `wrap` case (gh#741). */
9
+ const folderTags = [
10
+ { value: "design", label: "設計", count: 12 },
11
+ { value: "runbook", label: "運用手順", count: 148 },
12
+ { value: "security", label: "セキュリティ", count: 37 },
13
+ { value: "onboarding", label: "オンボーディング", count: 9 },
14
+ { value: "incident", label: "障害報告", count: 64 },
15
+ { value: "contract", label: "契約", count: 21 },
16
+ { value: "billing", label: "請求", count: 83 },
17
+ { value: "release", label: "リリース", count: 156 },
18
+ { value: "meeting", label: "議事録", count: 402 },
19
+ { value: "hr", label: "人事", count: 18 },
20
+ { value: "legal", label: "法務", count: 6 },
21
+ { value: "archive", label: "アーカイブ", count: 311 },
22
+ ];
23
+
8
24
  /**
9
25
  * ToggleGroup — single or multi-select toggle set. type='single' for mutually
10
26
  * exclusive modes; type='multiple' for independent selections. Never raw radio
@@ -14,6 +30,7 @@ export default function Demo() {
14
30
  const [period, setPeriod] = useState<string>("monthly");
15
31
  const [formats, setFormats] = useState<string[]>(["pdf"]);
16
32
  const [view, setView] = useState<string>("list");
33
+ const [tags, setTags] = useState<string[]>(["design", "runbook"]);
17
34
 
18
35
  return (
19
36
  <PageContainer
@@ -165,6 +182,72 @@ export default function Demo() {
165
182
  </CardContent>
166
183
  </Card>
167
184
 
185
+ <Card>
186
+ <CardHeader>
187
+ <CardTitle level={2}>wrap · 折り返すタグ絞り込みの行</CardTitle>
188
+ <CardDescription>
189
+ wrap
190
+ を付けた行は、レールに収まらなくなった時点で次の行へ折り返す(gh#741)。名前も真偽値も
191
+ data-wrap 属性も Flex と同じ。既定は false で、variant
192
+ によって既定を変えることはしない。320px のレールで測ると 4 項目のセグメントは wrap
193
+ の有無に関わらず 1 行 32px
194
+ のままで、変わるのは元から溢れていた行だけだからである。折り返しても gap は 1
195
+ つなので、行間と列間は同じ 4px になる。
196
+ </CardDescription>
197
+ </CardHeader>
198
+ <CardContent>
199
+ <Flex direction="col" gap="md">
200
+ <Flex direction="col" gap="sm">
201
+ <Text as="p" size="sm" tone="muted">
202
+ wrap · variant=&quot;soft&quot; shape=&quot;pill&quot; size=&quot;xs&quot; ·
203
+ タグが 12 個あっても ToggleGroup は 1 つのまま(value / onValueChange も 1
204
+ つ、矢印キーは折り返した行をまたいで DOM 順に進む)
205
+ </Text>
206
+ <ToggleGroup
207
+ type="multiple"
208
+ variant="soft"
209
+ shape="pill"
210
+ size="xs"
211
+ wrap
212
+ value={tags}
213
+ onValueChange={(v) => setTags(v as string[])}
214
+ aria-label="タグで絞り込み"
215
+ >
216
+ {folderTags.map((tag) => (
217
+ <ToggleGroupItem
218
+ key={tag.value}
219
+ value={tag.value}
220
+ count={tag.count}
221
+ countLabel="ページ"
222
+ >
223
+ {tag.label}
224
+ </ToggleGroupItem>
225
+ ))}
226
+ </ToggleGroup>
227
+ <Text as="p" size="sm" tone="muted">
228
+ 選択中: {tags.length === 0 ? "なし" : tags.join(" / ")}
229
+ </Text>
230
+ </Flex>
231
+ <Flex direction="col" gap="sm">
232
+ <Text as="p" size="sm" tone="muted">
233
+ wrap なし(既定)· セグメントは 1 行 32px のまま、何も変わらない
234
+ </Text>
235
+ <ToggleGroup
236
+ type="single"
237
+ variant="outline"
238
+ defaultValue="daily"
239
+ aria-label="集計単位"
240
+ >
241
+ <ToggleGroupItem value="daily">日次</ToggleGroupItem>
242
+ <ToggleGroupItem value="monthly">月次</ToggleGroupItem>
243
+ <ToggleGroupItem value="quarterly">四半期</ToggleGroupItem>
244
+ <ToggleGroupItem value="yearly">年次</ToggleGroupItem>
245
+ </ToggleGroup>
246
+ </Flex>
247
+ </Flex>
248
+ </CardContent>
249
+ </Card>
250
+
168
251
  <Card>
169
252
  <CardHeader>
170
253
  <CardTitle level={2}>size · xs / sm / md / lg</CardTitle>
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@godxjp/ui",
3
- "version": "27.10.0",
4
- "godxUiMcp": "27.10.0",
3
+ "version": "27.11.0",
4
+ "godxUiMcp": "27.11.0",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
7
7
  "type": "git",