@rivet-health/design-system 33.1.2 → 34.0.1

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.
@@ -1976,6 +1976,7 @@ var RivSelect;
1976
1976
  error: null,
1977
1977
  },
1978
1978
  sourceOptionGroups: [],
1979
+ originalOptionGroups: [],
1979
1980
  selection: {
1980
1981
  selected: new OptionSet(),
1981
1982
  },
@@ -1989,7 +1990,7 @@ var RivSelect;
1989
1990
  const actions = new Subject();
1990
1991
  const internalActions = new Subject();
1991
1992
  const coreStateWithSelectionSnapshot = merge(actions, internalActions).pipe(scan(([state, snapshot], action) => {
1992
- const newState = sideEffects(reduce(state, action), action, source, internalActions);
1993
+ const newState = sideEffects(reduce(state, action, options), action, source, internalActions);
1993
1994
  const newSelectionSnapshot = (action.type === 'openChange' && action.open) ||
1994
1995
  (action.type === 'loadComplete' &&
1995
1996
  (newState.display.open || options?.inline))
@@ -2004,7 +2005,7 @@ var RivSelect;
2004
2005
  const allOptionGroups = s.sourceOptionGroups.map(optionGroup => {
2005
2006
  return {
2006
2007
  ...optionGroup,
2007
- options: optionGroup.options.map(option => augmentOptionToFullOption(s, option)),
2008
+ options: optionGroup.options.map(option => augmentOptionToFullOption(s, option, options)),
2008
2009
  };
2009
2010
  });
2010
2011
  const topLevelOptions = getTopLevelOptions(allOptionGroups);
@@ -2244,7 +2245,10 @@ var RivSelect;
2244
2245
  : null),
2245
2246
  }));
2246
2247
  }
2247
- return [{ options: addHighlightsToOption(ordered) }];
2248
+ return {
2249
+ data: [{ options: addHighlightsToOption(ordered) }],
2250
+ originalData: data,
2251
+ };
2248
2252
  };
2249
2253
  return createManager(source, options);
2250
2254
  }
@@ -2381,7 +2385,16 @@ var RivSelect;
2381
2385
  if (options?.selectedOptionLimit === undefined) {
2382
2386
  return optionGroups;
2383
2387
  }
2384
- const selectedOrIndeterminateTopOptions = topLevelOptions.filter(option => option.selected != false);
2388
+ // When useTopLevelOptionsForDisplay is true and search is active, count
2389
+ // selected top-level options from the original (unfiltered) data to ensure
2390
+ // already-selected options that don't match the search are still counted.
2391
+ const useOriginalForCounting = options?.useTopLevelOptionsForDisplay &&
2392
+ state.query.search &&
2393
+ state.originalOptionGroups.length > 0;
2394
+ const topOptionsForCounting = useOriginalForCounting
2395
+ ? getTopLevelOptions(state.originalOptionGroups).map(option => augmentOptionToFullOption(state, option, options))
2396
+ : topLevelOptions;
2397
+ const selectedOrIndeterminateTopOptions = topOptionsForCounting.filter(option => option.selected != false);
2385
2398
  const numSelectedOptions = options?.useTopLevelOptionsForDisplay
2386
2399
  ? selectedOrIndeterminateTopOptions.length
2387
2400
  : state.selection.selected.size;
@@ -2461,17 +2474,47 @@ var RivSelect;
2461
2474
  return false;
2462
2475
  return 'indeterminate';
2463
2476
  }
2464
- function augmentOptionToFullOption(state, option) {
2477
+ function augmentOptionToFullOption(state, option, managerOptions) {
2465
2478
  if (option.children?.length) {
2466
- const augmentedChildren = option.children.map(child => augmentOptionToFullOption(state, child));
2479
+ const augmentedChildren = option.children.map(child => augmentOptionToFullOption(state, child, managerOptions));
2480
+ const selectableWhenSearching = managerOptions?.allowSelectNonLeafDuringSearch ?? false;
2481
+ // When allowSelectNonLeafDuringSearch is enabled and search is active,
2482
+ // calculate selection state from ALL original children, not just the
2483
+ // filtered ones visible in search results.
2484
+ const useOriginalForSelectionState = managerOptions?.allowSelectNonLeafDuringSearch &&
2485
+ state.query.search &&
2486
+ state.originalOptionGroups.length > 0;
2487
+ let selected;
2488
+ if (useOriginalForSelectionState) {
2489
+ const originalOption = findOption(getTopLevelOptions(state.originalOptionGroups), option.id);
2490
+ if (originalOption) {
2491
+ const allLeaves = flattenOptions([originalOption], true);
2492
+ const selectedCount = allLeaves.filter(leaf => state.selection.selected.has(leaf)).length;
2493
+ if (selectedCount === 0) {
2494
+ selected = false;
2495
+ }
2496
+ else if (selectedCount === allLeaves.length) {
2497
+ selected = true;
2498
+ }
2499
+ else {
2500
+ selected = 'indeterminate';
2501
+ }
2502
+ }
2503
+ else {
2504
+ selected = getParentMultiSelectionState(augmentedChildren);
2505
+ }
2506
+ }
2507
+ else {
2508
+ selected = getParentMultiSelectionState(augmentedChildren);
2509
+ }
2467
2510
  return {
2468
2511
  ...option,
2469
2512
  children: augmentedChildren,
2470
- selected: getParentMultiSelectionState(augmentedChildren),
2513
+ selected,
2471
2514
  expanded: state.query.search
2472
2515
  ? true
2473
2516
  : state.display.expandedOptions.has(option.id),
2474
- selectable: !state.query.search,
2517
+ selectable: !state.query.search || selectableWhenSearching,
2475
2518
  expandable: !state.query.search,
2476
2519
  };
2477
2520
  }
@@ -2542,14 +2585,23 @@ var RivSelect;
2542
2585
  }
2543
2586
  }));
2544
2587
  }
2545
- function toggleSelected(state, id) {
2588
+ function toggleSelected(state, id, managerOptions) {
2546
2589
  const topLevelOptions = getTopLevelOptions(state.sourceOptionGroups);
2547
2590
  const option = findOption(topLevelOptions, id);
2548
2591
  if (!option)
2549
2592
  return state;
2550
2593
  const newSelection = new OptionSet(state.selection.selected);
2551
- const newValue = !(augmentOptionToFullOption(state, option).selected === true);
2552
- const leaves = flattenOptions([option], true);
2594
+ const newValue = !(augmentOptionToFullOption(state, option, managerOptions).selected === true);
2595
+ // When allowSelectNonLeafDuringSearch is enabled and search is active,
2596
+ // use the original (unfiltered) data to get all children, not just
2597
+ // those visible in the filtered search results.
2598
+ const useOriginalData = managerOptions?.allowSelectNonLeafDuringSearch &&
2599
+ state.query.search &&
2600
+ state.originalOptionGroups.length > 0;
2601
+ const optionForLeaves = useOriginalData
2602
+ ? findOption(getTopLevelOptions(state.originalOptionGroups), id) ?? option
2603
+ : option;
2604
+ const leaves = flattenOptions([optionForLeaves], true);
2553
2605
  for (const leaf of leaves) {
2554
2606
  if (newValue) {
2555
2607
  newSelection.add(leaf);
@@ -2618,8 +2670,12 @@ var RivSelect;
2618
2670
  action.type === 'orderChange' ||
2619
2671
  (action.type === 'openChange' && action.open)) {
2620
2672
  source(state.query, action)
2621
- .then(data => {
2622
- internalActions.next({ type: 'loadComplete', data });
2673
+ .then(result => {
2674
+ const data = Array.isArray(result) ? result : result.data;
2675
+ const originalData = Array.isArray(result)
2676
+ ? undefined
2677
+ : result.originalData;
2678
+ internalActions.next({ type: 'loadComplete', data, originalData });
2623
2679
  })
2624
2680
  .catch(error => {
2625
2681
  // eslint-disable-next-line no-console
@@ -2636,7 +2692,7 @@ var RivSelect;
2636
2692
  }
2637
2693
  return state;
2638
2694
  }
2639
- function reduce(state, action) {
2695
+ function reduce(state, action, managerOptions) {
2640
2696
  switch (action.type) {
2641
2697
  case 'load':
2642
2698
  return state;
@@ -2648,6 +2704,7 @@ var RivSelect;
2648
2704
  error: null,
2649
2705
  },
2650
2706
  sourceOptionGroups: action.data,
2707
+ originalOptionGroups: action.originalData ?? [],
2651
2708
  };
2652
2709
  case 'loadError':
2653
2710
  return {
@@ -2691,7 +2748,7 @@ var RivSelect;
2691
2748
  selection: action.payload,
2692
2749
  };
2693
2750
  case 'toggleOptionSelected':
2694
- return toggleSelected(state, action.id);
2751
+ return toggleSelected(state, action.id, managerOptions);
2695
2752
  case 'setSelectedOption':
2696
2753
  return setSelectedOption(state, action.id);
2697
2754
  case 'visibleSelectedChange':
@@ -8381,7 +8438,7 @@ var Chart;
8381
8438
  : scaleUtc(timeseriesDomain(data), yRange);
8382
8439
  const dateFormat = (date) => formatedDate(config.dateFormat || 'day', date);
8383
8440
  const { pipe, fullPipe } = getPipes(config.valueType);
8384
- const yTicks = yScale.ticks(data.x.length - 1).map(tick => ({
8441
+ const yTicks = yScale.ticks(Math.max(data.x.length - 1, 1)).map(tick => ({
8385
8442
  y: yScale(tick),
8386
8443
  label: isNumber(tick)
8387
8444
  ? data.type == 'labeled'
@@ -8417,7 +8474,29 @@ var Chart;
8417
8474
  yPos: yValue,
8418
8475
  width,
8419
8476
  });
8420
- if (data.ys.length == 1 || config.groupingType == 'clustered') {
8477
+ //Don't draw anything for zero-value bars
8478
+ if (width == 0) {
8479
+ return '';
8480
+ }
8481
+ //These checks are to make sure we still round if all previous/later values are 0
8482
+ const allLeftZero = data.ys
8483
+ .slice(0, yIndex)
8484
+ .map(y => y.values[index])
8485
+ .filter(val => val != 0).length == 0;
8486
+ const leftSideRound = yIndex == 0 ||
8487
+ data.ys.length == 1 ||
8488
+ config.groupingType == 'clustered' ||
8489
+ allLeftZero;
8490
+ const allRightZero = data.ys
8491
+ .slice(yIndex + 1, data.ys.length)
8492
+ .map(y => y.values[index])
8493
+ //If the later data's value is the same as the current data's, that indicates 0 width
8494
+ .filter(val => val != data.ys[yIndex].values[index]).length == 0;
8495
+ const rightSideRound = yIndex == data.ys.length - 1 ||
8496
+ data.ys.length == 1 ||
8497
+ config.groupingType == 'clustered' ||
8498
+ allRightZero;
8499
+ if (leftSideRound && rightSideRound) {
8421
8500
  //Both-sides rounding variation
8422
8501
  const pathD = `
8423
8502
  M ${xValue + horR},${yValue}
@@ -8433,7 +8512,7 @@ var Chart;
8433
8512
  `;
8434
8513
  return pathD;
8435
8514
  }
8436
- if (yIndex == 0) {
8515
+ if (leftSideRound) {
8437
8516
  //Left-side rounding variation
8438
8517
  const pathD = `
8439
8518
  M ${xValue + horR},${yValue}
@@ -8447,7 +8526,7 @@ var Chart;
8447
8526
  `;
8448
8527
  return pathD;
8449
8528
  }
8450
- if (yIndex == data.ys.length - 1) {
8529
+ if (rightSideRound) {
8451
8530
  //Right-side rounding variation
8452
8531
  const pathD = `
8453
8532
  M ${xValue},${yValue}
@@ -8503,6 +8582,31 @@ var Chart;
8503
8582
  visibleYIndex = data.ys.length - 1;
8504
8583
  }
8505
8584
  const yIndex = visibleIndices[visibleYIndex];
8585
+ //Check if we've landed on a zero-width bar (only really relevant on ends)
8586
+ if (simplifiedHorizontalBars[visibleYIndex][xIndex].width == 0 &&
8587
+ config.groupingType == 'stacked') {
8588
+ let altBarFound = false;
8589
+ //Check upwards
8590
+ for (let i = visibleYIndex + 1; i < simplifiedHorizontalBars.length; i++) {
8591
+ if (altBarFound) {
8592
+ break;
8593
+ }
8594
+ if (simplifiedHorizontalBars[i][xIndex].width != 0) {
8595
+ visibleYIndex = i;
8596
+ altBarFound = true;
8597
+ }
8598
+ }
8599
+ //Check downwards
8600
+ for (let i = visibleYIndex - 1; i >= 0; i--) {
8601
+ if (altBarFound) {
8602
+ break;
8603
+ }
8604
+ if (simplifiedHorizontalBars[i][xIndex].width != 0) {
8605
+ visibleYIndex = i;
8606
+ altBarFound = true;
8607
+ }
8608
+ }
8609
+ }
8506
8610
  const anchor = new DOMRect(pos.rect.x +
8507
8611
  simplifiedHorizontalBars[visibleYIndex][xIndex].xPos -
8508
8612
  SMALL_PADDING, pos.rect.y + simplifiedHorizontalBars[visibleYIndex][xIndex].yPos, simplifiedHorizontalBars[visibleYIndex][xIndex].width +