@a4ui/core 0.35.2 → 0.37.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.
- package/dist/index.d.ts +1 -1
- package/dist/index.js +51 -21
- package/dist/ui/DataGrid.d.ts +12 -0
- package/dist/ui/LocationPicker.d.ts +29 -0
- package/package.json +1 -1
- package/src/index.ts +1 -1
- package/src/ui/DataGrid.tsx +15 -3
- package/src/ui/LocationPicker.tsx +46 -5
- package/src/ui/Table.tsx +9 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const A4UI_VERSION = "0.
|
|
1
|
+
export declare const A4UI_VERSION = "0.37.0";
|
|
2
2
|
export { cn } from './lib/cn';
|
|
3
3
|
export { useTheme, toggleTheme, setTheme, storedTheme, applyTheme, toggled, type Theme } from './lib/theme';
|
|
4
4
|
export { useEffects, isCalm, setEffects } from './lib/effects';
|
package/dist/index.js
CHANGED
|
@@ -1601,17 +1601,27 @@ function M$(e) {
|
|
|
1601
1601
|
})), l;
|
|
1602
1602
|
})();
|
|
1603
1603
|
}
|
|
1604
|
-
var mi = /* @__PURE__ */ x('<div class="w-full overflow-x-auto"><table>'), hi = /* @__PURE__ */ x("<thead>"), vi = /* @__PURE__ */ x("<tbody>"), bi = /* @__PURE__ */ x("<tr>"), xi = /* @__PURE__ */ x("<th>"), $i = /* @__PURE__ */ x("<td>");
|
|
1604
|
+
var mi = /* @__PURE__ */ x('<div class="relative w-full overflow-x-auto"><table>'), hi = /* @__PURE__ */ x("<thead>"), vi = /* @__PURE__ */ x("<tbody>"), bi = /* @__PURE__ */ x("<tr>"), xi = /* @__PURE__ */ x("<th>"), $i = /* @__PURE__ */ x("<td>");
|
|
1605
1605
|
function vr(e) {
|
|
1606
1606
|
const [t, n] = de(e, ["class", "children"]);
|
|
1607
|
-
return (
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1607
|
+
return (
|
|
1608
|
+
// `relative` is load-bearing, not decoration: `overflow` only clips a
|
|
1609
|
+
// descendant whose containing block is inside the scroller. Without a
|
|
1610
|
+
// positioned wrapper, an absolutely-positioned descendant (a
|
|
1611
|
+
// screen-reader-only input inside a cell control, for instance) resolves
|
|
1612
|
+
// against an ancestor further up, escapes the clip at the table's full
|
|
1613
|
+
// scroll width, and drags the whole DOCUMENT into horizontal scrolling —
|
|
1614
|
+
// measured on a phone: a 356 px table inside a 390 px viewport pushed the
|
|
1615
|
+
// page to 413 px.
|
|
1616
|
+
(() => {
|
|
1617
|
+
var r = mi(), l = r.firstChild;
|
|
1618
|
+
return ue(l, ge({
|
|
1619
|
+
get class() {
|
|
1620
|
+
return S("w-full border-collapse text-sm", t.class);
|
|
1621
|
+
}
|
|
1622
|
+
}, n), !1, !0), u(l, () => t.children), r;
|
|
1623
|
+
})()
|
|
1624
|
+
);
|
|
1615
1625
|
}
|
|
1616
1626
|
function Rt(e) {
|
|
1617
1627
|
const [t, n] = de(e, ["class", "children"]);
|
|
@@ -4354,8 +4364,12 @@ function Cy(e) {
|
|
|
4354
4364
|
onInput: (k) => {
|
|
4355
4365
|
n(k), a(1);
|
|
4356
4366
|
},
|
|
4357
|
-
placeholder
|
|
4358
|
-
|
|
4367
|
+
get placeholder() {
|
|
4368
|
+
return e.filterPlaceholder ?? "Filter…";
|
|
4369
|
+
},
|
|
4370
|
+
get "aria-label"() {
|
|
4371
|
+
return e.filterLabel ?? "Filter rows";
|
|
4372
|
+
}
|
|
4359
4373
|
})), w;
|
|
4360
4374
|
})();
|
|
4361
4375
|
})(), null), u(b, i(vr, {
|
|
@@ -4419,7 +4433,8 @@ function Cy(e) {
|
|
|
4419
4433
|
},
|
|
4420
4434
|
onChange: a,
|
|
4421
4435
|
get summary() {
|
|
4422
|
-
|
|
4436
|
+
var y;
|
|
4437
|
+
return ((y = e.rowsSummary) == null ? void 0 : y.call(e, f().length)) ?? `${f().length} rows`;
|
|
4423
4438
|
}
|
|
4424
4439
|
}), null), _(() => A(b, S("flex w-full flex-col rounded-lg border border-border bg-background", e.class))), b;
|
|
4425
4440
|
})();
|
|
@@ -10909,7 +10924,7 @@ function Uh(e) {
|
|
|
10909
10924
|
})();
|
|
10910
10925
|
}
|
|
10911
10926
|
G(["pointerdown"]);
|
|
10912
|
-
var Vh = /* @__PURE__ */ x('<div><div class="flex gap-2"><input type=text
|
|
10927
|
+
var Vh = /* @__PURE__ */ x('<div><div class="flex gap-2"><input type=text class="h-9 flex-1 rounded-md border border-border bg-input px-3 text-sm text-foreground placeholder:text-muted-foreground focus:ring-2 focus:ring-ring focus:outline-none">');
|
|
10913
10928
|
const Kh = 12, Gh = 240;
|
|
10914
10929
|
function Dw(e) {
|
|
10915
10930
|
const [t, n] = N(e.value ?? {
|
|
@@ -10930,10 +10945,15 @@ function Dw(e) {
|
|
|
10930
10945
|
label: c
|
|
10931
10946
|
});
|
|
10932
10947
|
}, o = () => {
|
|
10933
|
-
typeof navigator > "u" || !navigator.geolocation || navigator.geolocation.getCurrentPosition((c) =>
|
|
10934
|
-
|
|
10935
|
-
|
|
10936
|
-
|
|
10948
|
+
typeof navigator > "u" || !navigator.geolocation || navigator.geolocation.getCurrentPosition((c) => {
|
|
10949
|
+
var f;
|
|
10950
|
+
const d = {
|
|
10951
|
+
...r(),
|
|
10952
|
+
lat: c.coords.latitude,
|
|
10953
|
+
lng: c.coords.longitude
|
|
10954
|
+
};
|
|
10955
|
+
l(d), (f = e.onGeolocate) == null || f.call(e, d);
|
|
10956
|
+
}, (c) => console.error("LocationPicker: geolocation failed", c));
|
|
10937
10957
|
}, g = () => {
|
|
10938
10958
|
const {
|
|
10939
10959
|
lat: c,
|
|
@@ -10951,7 +10971,9 @@ function Dw(e) {
|
|
|
10951
10971
|
var c = Vh(), d = c.firstChild, f = d.firstChild;
|
|
10952
10972
|
return f.$$input = (m) => a(m.currentTarget.value), u(d, i(ce, {
|
|
10953
10973
|
variant: "outline",
|
|
10954
|
-
"aria-label"
|
|
10974
|
+
get "aria-label"() {
|
|
10975
|
+
return e.geolocateLabel ?? "Use my location";
|
|
10976
|
+
},
|
|
10955
10977
|
onClick: o,
|
|
10956
10978
|
get children() {
|
|
10957
10979
|
return i(po, {
|
|
@@ -10965,13 +10987,21 @@ function Dw(e) {
|
|
|
10965
10987
|
lng: r().lng
|
|
10966
10988
|
};
|
|
10967
10989
|
},
|
|
10968
|
-
zoom
|
|
10990
|
+
get zoom() {
|
|
10991
|
+
return e.zoom ?? Kh;
|
|
10992
|
+
},
|
|
10969
10993
|
height: Gh,
|
|
10970
10994
|
get markers() {
|
|
10971
10995
|
return g();
|
|
10972
10996
|
},
|
|
10973
10997
|
onClick: s
|
|
10974
|
-
}), null), _(() =>
|
|
10998
|
+
}), null), _((m) => {
|
|
10999
|
+
var h = S("flex flex-col gap-2", e.class), $ = e.labelPlaceholder ?? "Location label";
|
|
11000
|
+
return h !== m.e && A(c, m.e = h), $ !== m.t && I(f, "placeholder", m.t = $), m;
|
|
11001
|
+
}, {
|
|
11002
|
+
e: void 0,
|
|
11003
|
+
t: void 0
|
|
11004
|
+
}), _(() => f.value = r().label ?? ""), c;
|
|
10975
11005
|
})();
|
|
10976
11006
|
}
|
|
10977
11007
|
G(["input"]);
|
|
@@ -14838,7 +14868,7 @@ function j1() {
|
|
|
14838
14868
|
}
|
|
14839
14869
|
Tx(e && jl(e) || br);
|
|
14840
14870
|
}
|
|
14841
|
-
const D1 = "0.
|
|
14871
|
+
const D1 = "0.37.0";
|
|
14842
14872
|
export {
|
|
14843
14873
|
D1 as A4UI_VERSION,
|
|
14844
14874
|
g$ as Accordion,
|
package/dist/ui/DataGrid.d.ts
CHANGED
|
@@ -18,6 +18,18 @@ export interface DataGridProps {
|
|
|
18
18
|
pageSize?: number;
|
|
19
19
|
/** Show the global text filter above the table. Defaults to true. */
|
|
20
20
|
filterable?: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Copy overrides, for apps that do not run in English. Every user-visible
|
|
23
|
+
* string this component renders on its own is here; without them a Spanish
|
|
24
|
+
* or French page shows "Filter…" and "12 rows" in the middle of its own
|
|
25
|
+
* table with no way to change it.
|
|
26
|
+
* @default 'Filter…'
|
|
27
|
+
*/
|
|
28
|
+
filterPlaceholder?: string;
|
|
29
|
+
/** Accessible name for the filter box. @default 'Filter rows' */
|
|
30
|
+
filterLabel?: string;
|
|
31
|
+
/** Builds the row-count summary. @default (n) => `${n} rows` */
|
|
32
|
+
rowsSummary?: (count: number) => string;
|
|
21
33
|
class?: string;
|
|
22
34
|
}
|
|
23
35
|
/**
|
|
@@ -9,6 +9,35 @@ export interface LocationPickerProps {
|
|
|
9
9
|
value?: LocationValue;
|
|
10
10
|
/** Fires with the full value whenever the label, the pin, or geolocation changes it. */
|
|
11
11
|
onChange?: (v: LocationValue) => void;
|
|
12
|
+
/**
|
|
13
|
+
* Placeholder for the free-text label field. Overridable because this was
|
|
14
|
+
* hardcoded English inside an otherwise fully translatable component — a
|
|
15
|
+
* Spanish form showed "Location label" in the middle of its own wizard.
|
|
16
|
+
* @default 'Location label'
|
|
17
|
+
*/
|
|
18
|
+
labelPlaceholder?: string;
|
|
19
|
+
/** Accessible name for the "use my location" button. @default 'Use my location' */
|
|
20
|
+
geolocateLabel?: string;
|
|
21
|
+
/**
|
|
22
|
+
* Map zoom. Also acts as a zoom trigger the same way `center` does on
|
|
23
|
+
* `InteractiveMap` — passing a new value zooms there.
|
|
24
|
+
*
|
|
25
|
+
* Exposed because 12 (a whole city) is the wrong scale for confirming a
|
|
26
|
+
* pin: a consumer that wants to zoom in after a successful geolocation had
|
|
27
|
+
* no way to do it. @default 12
|
|
28
|
+
*/
|
|
29
|
+
zoom?: number;
|
|
30
|
+
/**
|
|
31
|
+
* Fires ONLY when the "use my location" button succeeds, in addition to
|
|
32
|
+
* `onChange`.
|
|
33
|
+
*
|
|
34
|
+
* `onChange` alone cannot tell a map click from a geolocation, so a
|
|
35
|
+
* consumer had no way to react to one and not the other. Recentring on a
|
|
36
|
+
* user already looking at their own city moves the map barely at all and
|
|
37
|
+
* leaves the pin dead centre, which reads as nothing having happened —
|
|
38
|
+
* this is the hook for saying otherwise.
|
|
39
|
+
*/
|
|
40
|
+
onGeolocate?: (v: LocationValue) => void;
|
|
12
41
|
class?: string;
|
|
13
42
|
}
|
|
14
43
|
/**
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
// import '@a4ui/core/styles.css'
|
|
9
9
|
// import { Button, Card, Modal } from '@a4ui/core'
|
|
10
10
|
|
|
11
|
-
export const A4UI_VERSION = '0.
|
|
11
|
+
export const A4UI_VERSION = '0.37.0'
|
|
12
12
|
|
|
13
13
|
// Helpers (src/lib) — generic, framework-level utilities.
|
|
14
14
|
export { cn } from './lib/cn'
|
package/src/ui/DataGrid.tsx
CHANGED
|
@@ -31,6 +31,18 @@ export interface DataGridProps {
|
|
|
31
31
|
pageSize?: number
|
|
32
32
|
/** Show the global text filter above the table. Defaults to true. */
|
|
33
33
|
filterable?: boolean
|
|
34
|
+
/**
|
|
35
|
+
* Copy overrides, for apps that do not run in English. Every user-visible
|
|
36
|
+
* string this component renders on its own is here; without them a Spanish
|
|
37
|
+
* or French page shows "Filter…" and "12 rows" in the middle of its own
|
|
38
|
+
* table with no way to change it.
|
|
39
|
+
* @default 'Filter…'
|
|
40
|
+
*/
|
|
41
|
+
filterPlaceholder?: string
|
|
42
|
+
/** Accessible name for the filter box. @default 'Filter rows' */
|
|
43
|
+
filterLabel?: string
|
|
44
|
+
/** Builds the row-count summary. @default (n) => `${n} rows` */
|
|
45
|
+
rowsSummary?: (count: number) => string
|
|
34
46
|
class?: string
|
|
35
47
|
}
|
|
36
48
|
|
|
@@ -126,8 +138,8 @@ export function DataGrid(props: DataGridProps): JSX.Element {
|
|
|
126
138
|
setQuery(v)
|
|
127
139
|
setPage(1)
|
|
128
140
|
}}
|
|
129
|
-
placeholder=
|
|
130
|
-
aria-label=
|
|
141
|
+
placeholder={props.filterPlaceholder ?? 'Filter…'}
|
|
142
|
+
aria-label={props.filterLabel ?? 'Filter rows'}
|
|
131
143
|
/>
|
|
132
144
|
</div>
|
|
133
145
|
)}
|
|
@@ -170,7 +182,7 @@ export function DataGrid(props: DataGridProps): JSX.Element {
|
|
|
170
182
|
page={Math.min(page(), totalPages())}
|
|
171
183
|
totalPages={totalPages()}
|
|
172
184
|
onChange={setPage}
|
|
173
|
-
summary={`${sorted().length} rows`}
|
|
185
|
+
summary={props.rowsSummary?.(sorted().length) ?? `${sorted().length} rows`}
|
|
174
186
|
/>
|
|
175
187
|
</div>
|
|
176
188
|
)
|
|
@@ -20,10 +20,39 @@ export interface LocationPickerProps {
|
|
|
20
20
|
value?: LocationValue
|
|
21
21
|
/** Fires with the full value whenever the label, the pin, or geolocation changes it. */
|
|
22
22
|
onChange?: (v: LocationValue) => void
|
|
23
|
+
/**
|
|
24
|
+
* Placeholder for the free-text label field. Overridable because this was
|
|
25
|
+
* hardcoded English inside an otherwise fully translatable component — a
|
|
26
|
+
* Spanish form showed "Location label" in the middle of its own wizard.
|
|
27
|
+
* @default 'Location label'
|
|
28
|
+
*/
|
|
29
|
+
labelPlaceholder?: string
|
|
30
|
+
/** Accessible name for the "use my location" button. @default 'Use my location' */
|
|
31
|
+
geolocateLabel?: string
|
|
32
|
+
/**
|
|
33
|
+
* Map zoom. Also acts as a zoom trigger the same way `center` does on
|
|
34
|
+
* `InteractiveMap` — passing a new value zooms there.
|
|
35
|
+
*
|
|
36
|
+
* Exposed because 12 (a whole city) is the wrong scale for confirming a
|
|
37
|
+
* pin: a consumer that wants to zoom in after a successful geolocation had
|
|
38
|
+
* no way to do it. @default 12
|
|
39
|
+
*/
|
|
40
|
+
zoom?: number
|
|
41
|
+
/**
|
|
42
|
+
* Fires ONLY when the "use my location" button succeeds, in addition to
|
|
43
|
+
* `onChange`.
|
|
44
|
+
*
|
|
45
|
+
* `onChange` alone cannot tell a map click from a geolocation, so a
|
|
46
|
+
* consumer had no way to react to one and not the other. Recentring on a
|
|
47
|
+
* user already looking at their own city moves the map barely at all and
|
|
48
|
+
* leaves the pin dead centre, which reads as nothing having happened —
|
|
49
|
+
* this is the hook for saying otherwise.
|
|
50
|
+
*/
|
|
51
|
+
onGeolocate?: (v: LocationValue) => void
|
|
23
52
|
class?: string
|
|
24
53
|
}
|
|
25
54
|
|
|
26
|
-
const
|
|
55
|
+
const DEFAULT_MAP_ZOOM = 12
|
|
27
56
|
const MAP_HEIGHT = 240
|
|
28
57
|
|
|
29
58
|
/**
|
|
@@ -60,7 +89,15 @@ export function LocationPicker(props: LocationPickerProps): JSX.Element {
|
|
|
60
89
|
const useMyLocation = (): void => {
|
|
61
90
|
if (typeof navigator === 'undefined' || !navigator.geolocation) return
|
|
62
91
|
navigator.geolocation.getCurrentPosition(
|
|
63
|
-
(position) =>
|
|
92
|
+
(position) => {
|
|
93
|
+
const next: LocationValue = {
|
|
94
|
+
...current(),
|
|
95
|
+
lat: position.coords.latitude,
|
|
96
|
+
lng: position.coords.longitude,
|
|
97
|
+
}
|
|
98
|
+
emit(next)
|
|
99
|
+
props.onGeolocate?.(next)
|
|
100
|
+
},
|
|
64
101
|
(error) => console.error('LocationPicker: geolocation failed', error),
|
|
65
102
|
)
|
|
66
103
|
}
|
|
@@ -77,16 +114,20 @@ export function LocationPicker(props: LocationPickerProps): JSX.Element {
|
|
|
77
114
|
type="text"
|
|
78
115
|
value={current().label ?? ''}
|
|
79
116
|
onInput={(event) => setLabel(event.currentTarget.value)}
|
|
80
|
-
placeholder=
|
|
117
|
+
placeholder={props.labelPlaceholder ?? 'Location label'}
|
|
81
118
|
class="h-9 flex-1 rounded-md border border-border bg-input px-3 text-sm text-foreground placeholder:text-muted-foreground focus:ring-2 focus:ring-ring focus:outline-none"
|
|
82
119
|
/>
|
|
83
|
-
<Button
|
|
120
|
+
<Button
|
|
121
|
+
variant="outline"
|
|
122
|
+
aria-label={props.geolocateLabel ?? 'Use my location'}
|
|
123
|
+
onClick={useMyLocation}
|
|
124
|
+
>
|
|
84
125
|
<Crosshair class="h-4 w-4" />
|
|
85
126
|
</Button>
|
|
86
127
|
</div>
|
|
87
128
|
<InteractiveMap
|
|
88
129
|
center={{ lat: current().lat, lng: current().lng }}
|
|
89
|
-
zoom={
|
|
130
|
+
zoom={props.zoom ?? DEFAULT_MAP_ZOOM}
|
|
90
131
|
height={MAP_HEIGHT}
|
|
91
132
|
markers={pin()}
|
|
92
133
|
onClick={setCoord}
|
package/src/ui/Table.tsx
CHANGED
|
@@ -34,7 +34,15 @@ interface TableProps extends ParentProps {
|
|
|
34
34
|
export function Table(props: TableProps): JSX.Element {
|
|
35
35
|
const [local, rest] = splitProps(props, ['class', 'children'])
|
|
36
36
|
return (
|
|
37
|
-
|
|
37
|
+
// `relative` is load-bearing, not decoration: `overflow` only clips a
|
|
38
|
+
// descendant whose containing block is inside the scroller. Without a
|
|
39
|
+
// positioned wrapper, an absolutely-positioned descendant (a
|
|
40
|
+
// screen-reader-only input inside a cell control, for instance) resolves
|
|
41
|
+
// against an ancestor further up, escapes the clip at the table's full
|
|
42
|
+
// scroll width, and drags the whole DOCUMENT into horizontal scrolling —
|
|
43
|
+
// measured on a phone: a 356 px table inside a 390 px viewport pushed the
|
|
44
|
+
// page to 413 px.
|
|
45
|
+
<div class="relative w-full overflow-x-auto">
|
|
38
46
|
<table class={cn('w-full border-collapse text-sm', local.class)} {...rest}>
|
|
39
47
|
{local.children}
|
|
40
48
|
</table>
|