@godxjp/ui 18.12.0 → 18.12.2

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.
@@ -2,11 +2,12 @@
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
3
  import * as React from "react";
4
4
  import * as SelectPrimitive from "@radix-ui/react-select";
5
- import { ChevronDown, ChevronUp } from "lucide-react";
5
+ import { ChevronDown, ChevronUp, X } from "lucide-react";
6
6
  import { cn } from "../../lib/utils.js";
7
7
  import { controlTriggerClass } from "../../lib/control-styles.js";
8
8
  import { mergeAriaIds, omitFieldA11y, pickFieldA11y } from "../../lib/field-a11y.js";
9
9
  import { SearchSelect } from "./search-select.js";
10
+ import { useTranslation } from "../../i18n/use-translation.js";
10
11
  function isDataSelect(props) {
11
12
  return "options" in props || "loadOptions" in props;
12
13
  }
@@ -203,6 +204,7 @@ function DataSelect({
203
204
  const ariaProps = Object.fromEntries(
204
205
  Object.entries(rest).filter(([key]) => key.startsWith("aria-"))
205
206
  );
207
+ const { t } = useTranslation();
206
208
  const searchable = showSearch ?? Boolean(loadOptions);
207
209
  const hasOptions = options.length > 0;
208
210
  if (searchable) {
@@ -255,7 +257,9 @@ function DataSelect({
255
257
  option.value
256
258
  );
257
259
  const isControlled = value !== void 0;
258
- return /* @__PURE__ */ jsxs(
260
+ const canClear = clearable !== false && isControlled && !disabled && !readOnly;
261
+ const showClear = canClear && Boolean(value);
262
+ const select = /* @__PURE__ */ jsxs(
259
263
  SelectPrimitive.Root,
260
264
  {
261
265
  "data-slot": "select",
@@ -268,7 +272,17 @@ function DataSelect({
268
272
  disabled: disabled || !hasOptions,
269
273
  name,
270
274
  children: [
271
- /* @__PURE__ */ jsx(SelectTrigger, { id, "data-testid": dataTestId, className, ...ariaProps, children: /* @__PURE__ */ jsx(SelectValue, { placeholder }) }),
275
+ /* @__PURE__ */ jsx(
276
+ SelectTrigger,
277
+ {
278
+ id,
279
+ "data-testid": dataTestId,
280
+ className: cn(showClear && "pe-9", canClear ? void 0 : className),
281
+ showIndicator: !showClear,
282
+ ...ariaProps,
283
+ children: /* @__PURE__ */ jsx(SelectValue, { placeholder })
284
+ }
285
+ ),
272
286
  /* @__PURE__ */ jsx(SelectContent, { children: groupDataOptions(options).map(
273
287
  (group) => group.heading ? /* @__PURE__ */ jsxs(SelectGroup, { children: [
274
288
  /* @__PURE__ */ jsx(SelectLabel, { children: group.heading }),
@@ -278,6 +292,21 @@ function DataSelect({
278
292
  ]
279
293
  }
280
294
  );
295
+ if (!canClear) return select;
296
+ return /* @__PURE__ */ jsxs("div", { className: cn("relative", className), children: [
297
+ select,
298
+ showClear ? /* @__PURE__ */ jsx("div", { className: "absolute inset-y-0 end-2 flex items-center", children: /* @__PURE__ */ jsx(
299
+ "button",
300
+ {
301
+ type: "button",
302
+ "aria-label": clearLabel ?? t("dataEntry.searchSelect.clear"),
303
+ "data-testid": dataTestId ? `${dataTestId}-clear` : void 0,
304
+ className: "flex size-6 items-center justify-center rounded-sm opacity-50 hover:opacity-100 focus-visible:opacity-100",
305
+ onClick: () => onValueChange?.("", void 0),
306
+ children: /* @__PURE__ */ jsx(X, { className: "size-4", "aria-hidden": "true" })
307
+ }
308
+ ) }) : null
309
+ ] });
281
310
  }
282
311
  export {
283
312
  Select,
@@ -1,7 +1,13 @@
1
1
  import type { ReactNode } from "react";
2
- import type { ResponsiveGridColumnsProp } from "../../props/components/layout.prop.js";
2
+ import type { ResponsiveGridColumnsProp, ResponsiveGridPresetProp } from "../../props/components/layout.prop.js";
3
3
  export type ResponsiveGridProps = {
4
4
  columns?: ResponsiveGridColumnsProp;
5
+ /**
6
+ * Named column geometry for a recognised collection shape — see `ResponsiveGridPresetProp`.
7
+ * Wins over `columns` when both are set, so a caller migrating to a preset does not also need
8
+ * to strip its old `columns` prop.
9
+ */
10
+ preset?: ResponsiveGridPresetProp;
5
11
  children: ReactNode;
6
12
  };
7
- export declare function ResponsiveGrid({ columns, children }: ResponsiveGridProps): import("react").JSX.Element;
13
+ export declare function ResponsiveGrid({ columns, preset, children }: ResponsiveGridProps): import("react").JSX.Element;
@@ -1,20 +1,31 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
+ const RESPONSIVE_GRID_PRESET_COLUMNS = {
3
+ "pricing-plans": { sm: 3, md: 3, lg: 3 }
4
+ };
2
5
  function resolveColumns(columns) {
3
6
  if (typeof columns === "number") {
4
7
  return {
5
- "--responsive-grid-sm": Math.min(columns, 2),
6
- "--responsive-grid-md": Math.min(columns, 3),
7
- "--responsive-grid-lg": columns
8
+ sm: Math.min(columns, 2),
9
+ md: Math.min(columns, 3),
10
+ lg: columns
8
11
  };
9
12
  }
10
13
  return {
11
- "--responsive-grid-sm": columns.sm ?? 1,
12
- "--responsive-grid-md": columns.md ?? columns.sm ?? 1,
13
- "--responsive-grid-lg": columns.lg ?? columns.md ?? columns.sm ?? 1
14
+ sm: columns.sm ?? 1,
15
+ md: columns.md ?? columns.sm ?? 1,
16
+ lg: columns.lg ?? columns.md ?? columns.sm ?? 1
17
+ };
18
+ }
19
+ function toStyle(resolved) {
20
+ return {
21
+ "--responsive-grid-sm": resolved.sm,
22
+ "--responsive-grid-md": resolved.md,
23
+ "--responsive-grid-lg": resolved.lg
14
24
  };
15
25
  }
16
- function ResponsiveGrid({ columns = 4, children }) {
17
- return /* @__PURE__ */ jsx("div", { className: "ui-responsive-grid-scope", children: /* @__PURE__ */ jsx("div", { className: "ui-responsive-grid", style: resolveColumns(columns), children }) });
26
+ function ResponsiveGrid({ columns = 4, preset, children }) {
27
+ const resolved = preset ? RESPONSIVE_GRID_PRESET_COLUMNS[preset] : resolveColumns(columns);
28
+ return /* @__PURE__ */ jsx("div", { className: "ui-responsive-grid-scope", children: /* @__PURE__ */ jsx("div", { className: "ui-responsive-grid", style: toStyle(resolved), children }) });
18
29
  }
19
30
  export {
20
31
  ResponsiveGrid
@@ -136,6 +136,19 @@ export type ResponsiveGridColumnsProp = number | {
136
136
  md?: number;
137
137
  lg?: number;
138
138
  };
139
+ /**
140
+ * Named, package-owned column geometry for ResponsiveGrid — the semantic alternative to a
141
+ * consumer hand-rolling a `columns={{ sm, md, lg }}` breakpoint map for a recognised collection
142
+ * shape. Takes priority over `columns` when both are set (`columns` is then ignored, not merged).
143
+ *
144
+ * `pricing-plans` — the canonical billing/pricing-plan collection: 1 column until the `lg` step
145
+ * (container ≥ 64rem), then 3 columns from `lg` upward. Because ResponsiveGrid has no step above
146
+ * `lg`, this reads as exactly 3 columns at BOTH the 1024px and 1440px reference widths and 1
147
+ * column at 390px — the 3/3/1 contract requested for the billing plan catalog
148
+ * (dxs-platform/platform#333, tracked upstream at dxs-platform/pkg-ui#14). General-purpose beyond
149
+ * pricing: any 3-up desktop / 1-up mobile collection (no intermediate `md` step) can reuse it.
150
+ */
151
+ export type ResponsiveGridPresetProp = "pricing-plans";
139
152
  export type MasterDetailRailWidthProp = "compact" | "standard";
140
153
  export type MasterDetailRailProp = "master" | "detail";
141
154
  /**
@@ -532,6 +532,11 @@ export declare const COMPONENT_PROP_REGISTRY: {
532
532
  readonly file: "components/layout.prop.ts";
533
533
  readonly vocabulary: readonly [];
534
534
  };
535
+ readonly ResponsiveGridPresetProp: {
536
+ readonly group: "layout";
537
+ readonly file: "components/layout.prop.ts";
538
+ readonly vocabulary: readonly [];
539
+ };
535
540
  readonly MasterDetailRailWidthProp: {
536
541
  readonly group: "layout";
537
542
  readonly file: "components/layout.prop.ts";
@@ -525,6 +525,7 @@ const COMPONENT_PROP_REGISTRY = {
525
525
  ]
526
526
  },
527
527
  ResponsiveGridColumnsProp: { group: "layout", file: "components/layout.prop.ts", vocabulary: [] },
528
+ ResponsiveGridPresetProp: { group: "layout", file: "components/layout.prop.ts", vocabulary: [] },
528
529
  MasterDetailRailWidthProp: {
529
530
  group: "layout",
530
531
  file: "components/layout.prop.ts",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@godxjp/ui",
3
- "version": "18.12.0",
4
- "godxUiMcp": "18.12.0",
3
+ "version": "18.12.2",
4
+ "godxUiMcp": "18.12.2",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
7
7
  "type": "git",