@geomak/ui 6.27.2 → 6.28.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.cjs CHANGED
@@ -5515,10 +5515,10 @@ function Pagination({
5515
5515
  }, [serverSide, options.perPage, picker]);
5516
5516
  const currentOpt = picker.find((o) => o.key === displayPerPageKey);
5517
5517
  const currentPerPageLabel = currentOpt?.label ?? currentOpt?.value ?? options.perPage ?? "";
5518
- const navBtn = (icon, disabled, onClick, title) => /* @__PURE__ */ jsxRuntime.jsx(Button_default, { variant: "outline", size: "sm", disabled, onClick, icon, className: "w-7 !px-0", "aria-label": title, title });
5518
+ const navBtn = (icon, disabled, onClick, title) => /* @__PURE__ */ jsxRuntime.jsx(Button_default, { variant: "outline", size: "sm", disabled, onClick, icon, className: "w-7 !px-0 focus-visible:!ring-offset-0", "aria-label": title, title });
5519
5519
  const chevronRight = /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, className: "h-4 w-4", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M9 5l7 7-7 7" }) });
5520
5520
  const doubleChevronRight = /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, className: "h-4 w-4", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M13 5l7 7-7 7M5 5l7 7-7 7" }) });
5521
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center justify-end gap-x-4 gap-y-3 pt-3", children: [
5521
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center justify-end gap-x-4 gap-y-3", children: [
5522
5522
  options.withPicker && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mr-auto flex items-center gap-2", children: [
5523
5523
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "whitespace-nowrap text-xs text-foreground-muted", children: "Rows per page" }),
5524
5524
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -5527,6 +5527,7 @@ function Pagination({
5527
5527
  variant: "outline",
5528
5528
  size: "sm",
5529
5529
  side: "top",
5530
+ className: "focus-visible:!ring-offset-0",
5530
5531
  label: String(currentPerPageLabel),
5531
5532
  items: picker.map((o) => ({
5532
5533
  key: o.key,
@@ -9161,6 +9162,116 @@ function ColorPicker({
9161
9162
  name && /* @__PURE__ */ jsxRuntime.jsx("input", { type: "hidden", name, value: valid ? value : "" })
9162
9163
  ] });
9163
9164
  }
9165
+ var CUSTOM_EVENT = "oxy-local-storage";
9166
+ function useLocalStorage(key, initialValue) {
9167
+ const read = React28.useCallback(() => {
9168
+ if (typeof window === "undefined") return initialValue;
9169
+ try {
9170
+ const item = window.localStorage.getItem(key);
9171
+ return item != null ? JSON.parse(item) : initialValue;
9172
+ } catch {
9173
+ return initialValue;
9174
+ }
9175
+ }, [key]);
9176
+ const [stored, setStored] = React28.useState(read);
9177
+ const setValue = React28.useCallback((value) => {
9178
+ setStored((prev) => {
9179
+ const next = value instanceof Function ? value(prev) : value;
9180
+ try {
9181
+ if (typeof window !== "undefined") {
9182
+ window.localStorage.setItem(key, JSON.stringify(next));
9183
+ window.dispatchEvent(new CustomEvent(CUSTOM_EVENT, { detail: key }));
9184
+ }
9185
+ } catch {
9186
+ }
9187
+ return next;
9188
+ });
9189
+ }, [key]);
9190
+ const remove = React28.useCallback(() => {
9191
+ try {
9192
+ if (typeof window !== "undefined") {
9193
+ window.localStorage.removeItem(key);
9194
+ window.dispatchEvent(new CustomEvent(CUSTOM_EVENT, { detail: key }));
9195
+ }
9196
+ } catch {
9197
+ }
9198
+ setStored(initialValue);
9199
+ }, [key]);
9200
+ React28.useEffect(() => {
9201
+ setStored(read());
9202
+ }, [key, read]);
9203
+ React28.useEffect(() => {
9204
+ if (typeof window === "undefined") return;
9205
+ const onStorage = (e) => {
9206
+ if (e.key === null || e.key === key) setStored(read());
9207
+ };
9208
+ const onCustom = (e) => {
9209
+ if (e.detail === key) setStored(read());
9210
+ };
9211
+ window.addEventListener("storage", onStorage);
9212
+ window.addEventListener(CUSTOM_EVENT, onCustom);
9213
+ return () => {
9214
+ window.removeEventListener("storage", onStorage);
9215
+ window.removeEventListener(CUSTOM_EVENT, onCustom);
9216
+ };
9217
+ }, [key, read]);
9218
+ return [stored, setValue, remove];
9219
+ }
9220
+ function useMediaQuery(query) {
9221
+ const get = () => typeof window !== "undefined" && typeof window.matchMedia === "function" ? window.matchMedia(query).matches : false;
9222
+ const [matches, setMatches] = React28.useState(get);
9223
+ React28.useEffect(() => {
9224
+ if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
9225
+ const mql = window.matchMedia(query);
9226
+ const onChange = () => setMatches(mql.matches);
9227
+ onChange();
9228
+ mql.addEventListener("change", onChange);
9229
+ return () => mql.removeEventListener("change", onChange);
9230
+ }, [query]);
9231
+ return matches;
9232
+ }
9233
+ var BREAKPOINTS = { sm: 480, md: 768, lg: 976, xl: 1440 };
9234
+ function useBreakpoint() {
9235
+ const sm = useMediaQuery(`(min-width: ${BREAKPOINTS.sm}px)`);
9236
+ const md = useMediaQuery(`(min-width: ${BREAKPOINTS.md}px)`);
9237
+ const lg = useMediaQuery(`(min-width: ${BREAKPOINTS.lg}px)`);
9238
+ const xl = useMediaQuery(`(min-width: ${BREAKPOINTS.xl}px)`);
9239
+ const active = xl ? "xl" : lg ? "lg" : md ? "md" : sm ? "sm" : "base";
9240
+ return { sm, md, lg, xl, active };
9241
+ }
9242
+ function decodeSegment(seg) {
9243
+ if (!seg || typeof atob === "undefined") return null;
9244
+ try {
9245
+ const json = decodeURIComponent(
9246
+ atob(seg.replace(/-/g, "+").replace(/_/g, "/")).split("").map((c) => "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2)).join("")
9247
+ );
9248
+ return JSON.parse(json);
9249
+ } catch {
9250
+ return null;
9251
+ }
9252
+ }
9253
+ function useJwt(token) {
9254
+ const [, tick] = React28.useState(0);
9255
+ const decoded = React28.useMemo(() => {
9256
+ if (!token) return { payload: null, header: null, exp: null };
9257
+ const [h, p] = token.split(".");
9258
+ const header = decodeSegment(h);
9259
+ const payload = decodeSegment(p);
9260
+ const exp = payload && typeof payload.exp === "number" ? payload.exp : null;
9261
+ return { payload, header, exp };
9262
+ }, [token]);
9263
+ React28.useEffect(() => {
9264
+ if (decoded.exp == null) return;
9265
+ const ms = decoded.exp * 1e3 - Date.now();
9266
+ if (ms <= 0) return;
9267
+ const id = setTimeout(() => tick((n) => n + 1), ms + 50);
9268
+ return () => clearTimeout(id);
9269
+ }, [decoded.exp]);
9270
+ const expiresAt = decoded.exp != null ? new Date(decoded.exp * 1e3) : null;
9271
+ const isExpired = decoded.exp != null ? decoded.exp * 1e3 <= Date.now() : false;
9272
+ const isValid = decoded.payload != null && !isExpired;
9273
+ return { payload: decoded.payload, header: decoded.header, expiresAt, isExpired, isValid, raw: token ?? null };
9274
+ }
9164
9275
 
9165
9276
  Object.defineProperty(exports, "COLORS", {
9166
9277
  enumerable: true,
@@ -9279,11 +9390,15 @@ exports.luhnValid = luhnValid;
9279
9390
  exports.onlyDigits = onlyDigits;
9280
9391
  exports.patterns = patterns;
9281
9392
  exports.runFieldRules = runFieldRules;
9393
+ exports.useBreakpoint = useBreakpoint;
9282
9394
  exports.useCart = useCart;
9283
9395
  exports.useFieldArray = useFieldArray;
9284
9396
  exports.useForm = useForm;
9285
9397
  exports.useFormField = useFormField;
9286
9398
  exports.useFormStore = useFormStore;
9399
+ exports.useJwt = useJwt;
9400
+ exports.useLocalStorage = useLocalStorage;
9401
+ exports.useMediaQuery = useMediaQuery;
9287
9402
  exports.useNotification = useNotification;
9288
9403
  //# sourceMappingURL=index.cjs.map
9289
9404
  //# sourceMappingURL=index.cjs.map