@jsenv/navi 0.27.19 → 0.27.21

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.
@@ -18403,6 +18403,14 @@ naviI18n.addAll({
18403
18403
  },
18404
18404
  });
18405
18405
 
18406
+ // Badge list messages
18407
+ naviI18n.addAll({
18408
+ "badge_list.more": {
18409
+ en: "+[count] more",
18410
+ fr: "+[count] de plus",
18411
+ },
18412
+ });
18413
+
18406
18414
  // Constraint validation messages — override any key to customize error messages
18407
18415
  naviI18n.addAll({
18408
18416
  "constraint.available": {
@@ -32019,19 +32027,6 @@ const RadioGroupInterface = props => {
32019
32027
  });
32020
32028
  };
32021
32029
 
32022
- const PickerPlaceholder = props => {
32023
- return jsx(Text, {
32024
- className: "navi_picker_placeholder",
32025
- ...props
32026
- });
32027
- };
32028
- const PickerValue = props => {
32029
- return jsx(Text, {
32030
- className: "navi_picker_value",
32031
- ...props
32032
- });
32033
- };
32034
-
32035
32030
  const PickerContext = createContext();
32036
32031
 
32037
32032
  const windowWidthSignal = signal(window.innerWidth);
@@ -32388,7 +32383,10 @@ const Popover = props => {
32388
32383
  popoverEl.removeAttribute("data-anchor-hidden");
32389
32384
  positionPopover(event);
32390
32385
  }, {
32391
- event: e
32386
+ event: e,
32387
+ // it's ok for the popover to become unsync with the anchor size
32388
+ // (we could even argue it's a feature as it helps to keep the popover position stable)
32389
+ skipElementResize: true
32392
32390
  });
32393
32391
  addCleanup(() => {
32394
32392
  rectEffect.disconnect();
@@ -33458,7 +33456,7 @@ const PickerText = props => {
33458
33456
  const PickerArray = props => {
33459
33457
  const Next = useNextResolver();
33460
33458
  return jsx(Next, {
33461
- "data-multiline": "",
33459
+ maxRows: 3,
33462
33460
  ui: jsx(PickerArrayUI, {}),
33463
33461
  ...props,
33464
33462
  type: "navi_picker"
@@ -33473,11 +33471,9 @@ const PickerArrayUI = () => {
33473
33471
  if (!placeholder) {
33474
33472
  return null;
33475
33473
  }
33476
- return jsx(PickerPlaceholder, {
33477
- children: placeholder
33478
- });
33474
+ return placeholder;
33479
33475
  }
33480
- return jsx(PickerValue, {
33476
+ return jsx(Text, {
33481
33477
  spacing: ", ",
33482
33478
  shrinkWrap: true,
33483
33479
  children: value.map(item => {
@@ -33505,9 +33501,7 @@ const PickerColorUI = () => {
33505
33501
  if (!placeholder) {
33506
33502
  return jsx(Color, {});
33507
33503
  }
33508
- return jsx(PickerPlaceholder, {
33509
- children: placeholder
33510
- });
33504
+ return placeholder;
33511
33505
  }
33512
33506
  return jsx(Color, {
33513
33507
  children: value
@@ -33535,9 +33529,7 @@ const PickerDateUI = props => {
33535
33529
  ...props
33536
33530
  });
33537
33531
  }
33538
- return jsx(PickerPlaceholder, {
33539
- children: placeholder
33540
- });
33532
+ return placeholder;
33541
33533
  }
33542
33534
  return jsx(Time, {
33543
33535
  type: "date",
@@ -33567,9 +33559,7 @@ const PickerMonthUI = () => {
33567
33559
  color: "var(--picker-placeholder-color"
33568
33560
  });
33569
33561
  }
33570
- return jsx(PickerPlaceholder, {
33571
- children: placeholder
33572
- });
33562
+ return placeholder;
33573
33563
  }
33574
33564
  return jsx(Time, {
33575
33565
  type: "month",
@@ -33598,9 +33588,7 @@ const PickerWeekUI = () => {
33598
33588
  color: "var(--picker-placeholder-color"
33599
33589
  });
33600
33590
  }
33601
- return jsx(PickerPlaceholder, {
33602
- children: placeholder
33603
- });
33591
+ return placeholder;
33604
33592
  }
33605
33593
  return jsx(Time, {
33606
33594
  type: "week",
@@ -33630,9 +33618,7 @@ const PickerTimeUI = props => {
33630
33618
  ...props
33631
33619
  });
33632
33620
  }
33633
- return jsx(PickerPlaceholder, {
33634
- children: placeholder
33635
- });
33621
+ return placeholder;
33636
33622
  }
33637
33623
  return jsx(Time, {
33638
33624
  type: "time",
@@ -33661,9 +33647,7 @@ const PickerDatetimeUI = () => {
33661
33647
  color: "var(--picker-placeholder-color"
33662
33648
  });
33663
33649
  }
33664
- return jsx(PickerPlaceholder, {
33665
- children: placeholder
33666
- });
33650
+ return placeholder;
33667
33651
  }
33668
33652
  return jsx(Time, {
33669
33653
  type: "datetime",
@@ -33688,14 +33672,10 @@ const PickerFileUI = () => {
33688
33672
  if (!placeholder) {
33689
33673
  return null;
33690
33674
  }
33691
- return jsx(PickerPlaceholder, {
33692
- children: "placeholder"
33693
- });
33675
+ return placeholder;
33694
33676
  }
33695
33677
  // value is a FileList-like string from the input; display file names
33696
- return jsx(PickerValue, {
33697
- children: value
33698
- });
33678
+ return value;
33699
33679
  };
33700
33680
  const PencilSvg = () => {
33701
33681
  return jsx("svg", {
@@ -34256,11 +34236,11 @@ installImportMetaCssBuild(import.meta);const css$m = /* css */`
34256
34236
  --list-item-outline-width: 2px;
34257
34237
  --list-item-outline-offset: calc(-1 * var(--list-item-outline-width));
34258
34238
  /* Hover (mouse) */
34259
- --list-item-color-hover: var(--list-item-color);
34260
34239
  --list-item-background-color-hover: light-dark(#f5f5f5, #2a2a2a);
34240
+ --list-item-color-hover: var(--list-item-color);
34261
34241
  /* Pointed by mouse — subtle, just a shade above background */
34262
- --list-item-color-mouse-pointed: var(--list-item-color);
34263
34242
  --list-item-background-color-mouse-pointed: light-dark(#ebebeb, #303030);
34243
+ --list-item-color-mouse-pointed: var(--list-item-color);
34264
34244
  /* Pointed by keyboard — subtle light blue highlight */
34265
34245
  --list-item-color-keyboard-pointed: var(--list-item-color);
34266
34246
  --list-item-background-color-keyboard-pointed: light-dark(
@@ -34268,8 +34248,8 @@ installImportMetaCssBuild(import.meta);const css$m = /* css */`
34268
34248
  #1c3a6e
34269
34249
  );
34270
34250
  /* Pointed by proxy */
34271
- --list-item-color-pointed: var(--list-item-color);
34272
34251
  --list-item-background-color-pointed: light-dark(#dbeafe, #1c3a6e);
34252
+ --list-item-color-pointed: var(--list-item-color);
34273
34253
  /* Selected — vivid blue accent */
34274
34254
  --list-item-color-selected: white;
34275
34255
  --list-item-background-color-selected: rgb(3, 30, 60);
@@ -34351,7 +34331,7 @@ installImportMetaCssBuild(import.meta);const css$m = /* css */`
34351
34331
  }
34352
34332
  /* No input proxy: focused,selected */
34353
34333
  &:not(:has(input[navi-control-proxy-for])) {
34354
- &:has([data-focus-visible]) {
34334
+ &:has([navi-selectable-real-input][data-focus-visible]) {
34355
34335
  --x-list-item-color: var(--list-item-color-keyboard-pointed);
34356
34336
  --x-list-item-background-color: var(
34357
34337
  --list-item-background-color-keyboard-pointed
@@ -34364,6 +34344,10 @@ installImportMetaCssBuild(import.meta);const css$m = /* css */`
34364
34344
  --list-item-background-color-selected,
34365
34345
  var(--list-item-background-color-keyboard-pointed)
34366
34346
  );
34347
+ --x-list-item-color: var(
34348
+ --list-item-color-selected,
34349
+ var(--list-item-color-keyboard-pointed)
34350
+ );
34367
34351
  }
34368
34352
  }
34369
34353
 
@@ -36364,7 +36348,6 @@ installImportMetaCssBuild(import.meta);const css$k = /* css */`
36364
36348
  --picker-border-radius: 2px;
36365
36349
  --picker-outline-width: 1px;
36366
36350
  --picker-border-width: 1px;
36367
- --picker-font-size: 14px;
36368
36351
  --picker-padding-x-default: 8px;
36369
36352
  --picker-padding-y-default: 5px;
36370
36353
  --picker-outline-color: var(--navi-focus-outline-color);
@@ -36378,7 +36361,6 @@ installImportMetaCssBuild(import.meta);const css$k = /* css */`
36378
36361
  transparent
36379
36362
  );
36380
36363
  --picker-color-dimmed: color-mix(in srgb, currentColor 60%, transparent);
36381
- --picker-right-slot-size: 1em;
36382
36364
  /* Hover */
36383
36365
  --picker-border-color-hover: color-mix(
36384
36366
  in srgb,
@@ -36431,17 +36413,13 @@ installImportMetaCssBuild(import.meta);const css$k = /* css */`
36431
36413
  var(--picker-padding, var(--picker-padding-y-default))
36432
36414
  )
36433
36415
  );
36434
- --x-picker-padding-right-base: var(
36416
+ --x-picker-padding-right: var(
36435
36417
  --picker-padding-right,
36436
36418
  var(
36437
36419
  --picker-padding-x,
36438
36420
  var(--picker-padding, var(--picker-padding-x-default))
36439
36421
  )
36440
36422
  );
36441
- --x-picker-padding-right: calc(
36442
- var(--x-picker-padding-right-base) + var(--picker-right-slot-size) +
36443
- var(--picker-right-slot-size) * 0.25
36444
- );
36445
36423
  --x-picker-padding-left: var(
36446
36424
  --picker-padding-left,
36447
36425
  var(
@@ -36460,7 +36438,7 @@ installImportMetaCssBuild(import.meta);const css$k = /* css */`
36460
36438
  --x-picker-icon-color: var(--picker-icon-color);
36461
36439
 
36462
36440
  position: relative;
36463
- display: inline-block;
36441
+ display: inline-flex;
36464
36442
  box-sizing: border-box;
36465
36443
  max-width: 100%;
36466
36444
  min-height: calc(
@@ -36471,8 +36449,9 @@ installImportMetaCssBuild(import.meta);const css$k = /* css */`
36471
36449
  padding-bottom: var(--x-picker-padding-bottom);
36472
36450
  padding-left: var(--x-picker-padding-left);
36473
36451
  flex-direction: row;
36452
+ align-items: center;
36453
+ gap: var(--navi-xs);
36474
36454
  color: var(--x-picker-color);
36475
- font-size: var(--picker-font-size);
36476
36455
  text-align: inherit;
36477
36456
  text-overflow: ellipsis;
36478
36457
  background-color: var(--x-picker-background-color);
@@ -36490,29 +36469,32 @@ installImportMetaCssBuild(import.meta);const css$k = /* css */`
36490
36469
  overflow: hidden;
36491
36470
 
36492
36471
  .navi_picker_value {
36493
- display: block;
36472
+ display: inline-block;
36494
36473
  min-width: 0;
36495
36474
  max-width: 100%;
36475
+ flex-grow: 1;
36496
36476
  text-overflow: ellipsis;
36497
36477
  white-space: nowrap;
36498
36478
  overflow: hidden;
36499
- }
36500
- .navi_picker_placeholder {
36501
- display: block;
36502
- max-width: 100%;
36503
- color: var(--picker-placeholder-color);
36504
- text-overflow: ellipsis;
36505
- white-space: nowrap;
36506
- overflow: hidden;
36479
+
36480
+ &[navi-placeholder] {
36481
+ color: var(--picker-placeholder-color);
36482
+ }
36483
+
36484
+ .navi_text:not(.navi_more_badge) {
36485
+ max-width: 100%;
36486
+ text-overflow: inherit;
36487
+ vertical-align: middle; /* For some reason it's required to disminish inline-block height */
36488
+ overflow: inherit;
36489
+ }
36507
36490
  }
36508
36491
  .navi_picker_right_slot {
36509
- position: absolute;
36510
- top: 0;
36511
- right: var(--x-picker-padding-right-base);
36512
36492
  display: inline-flex;
36513
- width: var(--picker-right-slot-size);
36514
- padding-top: var(--x-picker-padding-top);
36493
+ height: 1em;
36494
+ height: 1lh;
36515
36495
  flex-shrink: 0;
36496
+ align-items: center;
36497
+ align-self: flex-start;
36516
36498
  justify-content: center;
36517
36499
  color: var(--x-picker-icon-color);
36518
36500
  transform: translateX(25%);
@@ -36532,14 +36514,13 @@ installImportMetaCssBuild(import.meta);const css$k = /* css */`
36532
36514
  pointer-events: none;
36533
36515
  }
36534
36516
 
36535
- &[data-multiline] {
36517
+ &[data-line-clamp] {
36536
36518
  overflow-wrap: anywhere;
36537
-
36538
- .navi_picker_placeholder {
36539
- white-space: normal;
36540
- }
36541
36519
  .navi_picker_value {
36520
+ display: -webkit-box;
36542
36521
  white-space: normal;
36522
+ -webkit-box-orient: vertical;
36523
+ -webkit-line-clamp: var(--picker-max-rows);
36543
36524
  }
36544
36525
  }
36545
36526
 
@@ -36613,8 +36594,8 @@ const PickerButton = props => {
36613
36594
  ref,
36614
36595
  icon,
36615
36596
  placeholder,
36616
- singleLine,
36617
- ui
36597
+ ui,
36598
+ maxRows
36618
36599
  } = props;
36619
36600
  const inputRef = useRef(null);
36620
36601
  const [inputProps, pickerRemainingProps] = useControlProps({
@@ -36636,6 +36617,7 @@ const PickerButton = props => {
36636
36617
  children
36637
36618
  } = inputProps;
36638
36619
  const loading = basePseudoState[":-navi-loading"];
36620
+ const hasLineClamp = maxRows && maxRows > 1;
36639
36621
  return jsxs(Box, {
36640
36622
  as: "button",
36641
36623
  ref: ref,
@@ -36644,7 +36626,10 @@ const PickerButton = props => {
36644
36626
  "navi-has-placeholder": placeholder ? "" : undefined,
36645
36627
  pseudoClasses: PICKER_BUTTON_PSEUDO_CLASSES,
36646
36628
  disabled: disabled,
36647
- "data-single-line": singleLine ? "" : undefined,
36629
+ "data-line-clamp": hasLineClamp ? "" : undefined,
36630
+ style: {
36631
+ "--picker-max-rows": maxRows || -1
36632
+ },
36648
36633
  ...pickerRemainingProps,
36649
36634
  basePseudoState: basePseudoState,
36650
36635
  styleCSSVars: PickerStyleCSSVars
@@ -36655,7 +36640,7 @@ const PickerButton = props => {
36655
36640
  id: id,
36656
36641
  icon: undefined,
36657
36642
  ui: undefined,
36658
- singleLine: undefined,
36643
+ maxRows: undefined,
36659
36644
  dayLabel: undefined
36660
36645
  // The button is handling the pointer interactions
36661
36646
  ,
@@ -36686,12 +36671,17 @@ const PickerButton = props => {
36686
36671
  onMouseDown: undefined,
36687
36672
  onClick: undefined,
36688
36673
  onKeyDown: undefined
36689
- }), jsx(PickerContext.Provider, {
36690
- value: {
36691
- value,
36692
- placeholder
36693
- },
36694
- children: ui === undefined ? jsx(PickerDefaultUI, {}) : ui
36674
+ }), jsx(Text, {
36675
+ className: "navi_picker_value",
36676
+ "navi-placeholder": value === undefined || value === "" ? "" : undefined,
36677
+ children: jsx(PickerContext.Provider, {
36678
+ value: {
36679
+ value,
36680
+ placeholder,
36681
+ maxRows
36682
+ },
36683
+ children: ui === undefined ? jsx(PickerDefaultUI, {}) : ui
36684
+ })
36695
36685
  }), jsx("span", {
36696
36686
  className: "navi_picker_right_slot",
36697
36687
  children: jsx(Icon, {
@@ -36755,13 +36745,9 @@ const PickerDefaultUI = () => {
36755
36745
  if (!placeholder) {
36756
36746
  return null;
36757
36747
  }
36758
- return jsx(PickerPlaceholder, {
36759
- children: placeholder
36760
- });
36748
+ return placeholder;
36761
36749
  }
36762
- return jsx(PickerValue, {
36763
- children: value
36764
- });
36750
+ return value;
36765
36751
  };
36766
36752
  const PickerFirstResolver = props => {
36767
36753
  const Next = useNextResolver();
@@ -36775,8 +36761,6 @@ const PickerFirstResolver = props => {
36775
36761
  });
36776
36762
  };
36777
36763
  const Picker = createComponentResolver([PickerFirstResolver, ...pickerResolvers, PickerButton]);
36778
- Picker.Placeholder = PickerPlaceholder;
36779
- Picker.Value = PickerValue;
36780
36764
  Picker.UI = PickerDefaultUI;
36781
36765
  Picker.UI.Date = PickerDateUI;
36782
36766
  Picker.UI.Time = PickerTimeUI;
@@ -41336,63 +41320,96 @@ installImportMetaCssBuild(import.meta);const css$9 = /* css */`
41336
41320
  }
41337
41321
  .navi_badge_list {
41338
41322
  flex-wrap: wrap;
41323
+
41324
+ &[navi-badge-list-clone] {
41325
+ position: absolute;
41326
+ width: 100%;
41327
+ visibility: hidden;
41328
+ pointer-events: none;
41329
+ }
41330
+ }
41331
+
41332
+ .navi_badge.navi_badge_more {
41333
+ white-space: nowrap;
41339
41334
  }
41340
41335
  `;
41341
41336
  const BadgeList = ({
41342
41337
  fallback,
41343
41338
  children,
41344
- className,
41345
41339
  shrinkWrap = true,
41340
+ max,
41341
+ maxRows,
41346
41342
  ...props
41347
41343
  }) => {
41348
41344
  import.meta.css = [css$9, "@jsenv/navi/src/text/badge_list.jsx"];
41349
- const defaultRef = useRef();
41350
- props.ref = props.ref || defaultRef;
41351
- const {
41352
- ref
41353
- } = props;
41345
+ const measureRef = useRef();
41346
+ const visibleRef = useRef();
41354
41347
  useLayoutEffect(() => {
41355
- if (!shrinkWrap) {
41356
- return undefined;
41357
- }
41358
- const el = ref.current;
41359
- if (!el) {
41348
+ const measureEl = measureRef.current;
41349
+ const visibleEl = visibleRef.current;
41350
+ if (!measureEl || !visibleEl) {
41360
41351
  return undefined;
41361
41352
  }
41362
41353
  let observer;
41363
41354
  let rafId;
41364
- const applyWidth = () => {
41365
- el.style.width = "";
41366
- const optimalWidth = measureWidestChildRow(el);
41367
- if (optimalWidth === null) {
41368
- return;
41355
+ const measure = () => {
41356
+ visibleEl.style.width = "";
41357
+ if (shrinkWrap) {
41358
+ const optimalWidth = measureWidestChildRow(measureEl);
41359
+ if (optimalWidth !== null) {
41360
+ visibleEl.style.width = `${Math.ceil(optimalWidth)}px`;
41361
+ }
41369
41362
  }
41370
- el.style.width = `${Math.ceil(optimalWidth)}px`;
41371
41363
  };
41372
- applyWidth();
41373
- const parent = el.parentElement;
41374
- if (parent) {
41375
- observer = new ResizeObserver(() => {
41376
- cancelAnimationFrame(rafId);
41377
- rafId = requestAnimationFrame(applyWidth);
41378
- });
41379
- observer.observe(parent);
41364
+ measure();
41365
+ const onResize = () => {
41366
+ cancelAnimationFrame(rafId);
41367
+ rafId = requestAnimationFrame(measure);
41368
+ };
41369
+ const outerParent = measureEl.parentElement?.parentElement;
41370
+ if (outerParent) {
41371
+ observer = new ResizeObserver(onResize);
41372
+ observer.observe(outerParent);
41380
41373
  }
41381
- window.addEventListener("resize", applyWidth);
41374
+ window.addEventListener("resize", onResize);
41382
41375
  return () => {
41383
41376
  cancelAnimationFrame(rafId);
41384
41377
  observer?.disconnect();
41385
- window.removeEventListener("resize", applyWidth);
41378
+ window.removeEventListener("resize", onResize);
41386
41379
  };
41387
- });
41380
+ }, [shrinkWrap, children]);
41388
41381
  const childArray = toChildArray(children);
41389
- return jsx(Box, {
41382
+ const hasMax = max !== undefined && childArray.length > max;
41383
+ const visibleChildren = hasMax ? childArray.slice(0, max - 1) : childArray;
41384
+ const hiddenCount = hasMax ? childArray.length - (max - 1) : 0;
41385
+ const sharedProps = {
41386
+ inline: true,
41390
41387
  flex: "x",
41391
41388
  alignY: "center",
41392
41389
  spacing: "xs",
41393
- className: withPropsClassName("navi_badge_list", className),
41394
- ...props,
41395
- children: childArray.length ? children : fallback
41390
+ ...props
41391
+ };
41392
+ return jsxs(Box, {
41393
+ relative: true,
41394
+ children: [jsx(Box, {
41395
+ baseClassName: "navi_badge_list",
41396
+ ...sharedProps,
41397
+ ref: measureRef,
41398
+ "aria-hidden": "true",
41399
+ "navi-badge-list-clone": "",
41400
+ children: childArray
41401
+ }), jsxs(Box, {
41402
+ baseClassName: "navi_badge_list",
41403
+ ...sharedProps,
41404
+ ref: visibleRef,
41405
+ lineClamp: maxRows,
41406
+ children: [visibleChildren.length ? visibleChildren : fallback, hiddenCount > 0 && jsx(Badge, {
41407
+ className: "navi_badge_more",
41408
+ children: naviI18n("badge_list.more", {
41409
+ count: hiddenCount
41410
+ })
41411
+ })]
41412
+ })]
41396
41413
  });
41397
41414
  };
41398
41415