@ni/nimble-components 29.7.7 → 29.7.9

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.
@@ -9,6 +9,7 @@ import { focusVisible } from '../../utilities/style/focus';
9
9
  import { themeBehavior } from '../../utilities/style/theme';
10
10
  import { DropdownAppearance } from './types';
11
11
  import { userSelectNone } from '../../utilities/style/user-select';
12
+ // prettier-ignore
12
13
  export const styles = css `
13
14
  ${display('inline-flex')}
14
15
 
@@ -120,18 +121,23 @@ export const styles = css `
120
121
  flex-direction: column;
121
122
  overflow-y: auto;
122
123
  width: 100%;
124
+ --ni-private-listbox-visible-option-count: 10.5;
125
+ --ni-private-listbox-anchor-element-gap: ${smallPadding};
123
126
  --ni-private-listbox-padding: ${smallPadding};
124
127
  --ni-private-listbox-filter-height: 0px;
125
128
  --ni-private-listbox-loading-indicator-height: 0px;
126
129
  max-height: min(
127
130
  calc(
128
- ${smallPadding} + 2 * ${borderWidth} + ${controlHeight} * 10.5 +
129
- var(--ni-private-listbox-filter-height) +
130
- var(--ni-private-listbox-loading-indicator-height)
131
+ var(--ni-private-listbox-anchor-element-gap) +
132
+ 2 * ${borderWidth} +
133
+ var(--ni-private-listbox-padding) +
134
+ ${controlHeight} * var(--ni-private-listbox-visible-option-count) +
135
+ var(--ni-private-listbox-filter-height) +
136
+ var(--ni-private-listbox-loading-indicator-height)
131
137
  ),
132
138
  calc(
133
- var(--ni-private-listbox-available-viewport-height) -
134
- ${smallPadding}
139
+ var(--ni-private-listbox-available-viewport-height) -
140
+ var(--ni-private-listbox-anchor-element-gap)
135
141
  )
136
142
  );
137
143
  box-shadow: ${elevation2BoxShadow};
@@ -1 +1 @@
1
- {"version":3,"file":"styles.js","sourceRoot":"","sources":["../../../../src/patterns/dropdown/styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,yBAAyB,CAAC;AAC9C,OAAO,EAAE,KAAK,EAAE,MAAM,kDAAkD,CAAC;AACzE,OAAO,EAAE,OAAO,EAAE,MAAM,+BAA+B,CAAC;AACxD,OAAO,EACH,0BAA0B,EAC1B,QAAQ,EACR,aAAa,EACb,qBAAqB,EACrB,gBAAgB,EAChB,WAAW,EACX,aAAa,EACb,QAAQ,EACR,YAAY,EACZ,gBAAgB,EAChB,UAAU,EACV,YAAY,EACZ,qBAAqB,EACrB,aAAa,EACb,SAAS,EACT,mBAAmB,EACtB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAEnE,MAAM,CAAC,MAAM,MAAM,GAAG,GAAG,CAAA;MACnB,OAAO,CAAC,aAAa,CAAC;;;iBAGX,aAAa;gBACd,QAAQ;kBACN,aAAa;;;UAGrB,cAAc;qBACH,YAAY;;;mDAGkB,WAAW;;;;;;;;uBAQvC,WAAW;;;;yBAIT,gBAAgB;;4BAEb,UAAU;;;;;;;;;YAS1B,YAAY;;;;;+BAKO,SAAS;;;;;;4BAMZ,WAAW;;;;yBAId,gBAAgB;;4BAEb,UAAU;;;;;;;;;;YAU1B,YAAY;;;;;+BAKO,SAAS;;;;;;;;;;;;;;;;;iCAiBP,qBAAqB;;mBAEnC,WAAW;;;;+BAIC,gBAAgB;;;;;iBAK9B,qBAAqB;6BACT,qBAAqB;;;;;;+BAMnB,SAAS;;;;;;;;wCAQA,YAAY;;;;;kBAKlC,YAAY,UAAU,WAAW,MAAM,aAAa;;;;;;sBAMhD,YAAY;;;sBAGZ,mBAAmB;kBACvB,WAAW,UAAU,gBAAgB;4BAC3B,0BAA0B;;;;8CAIR,aAAa;;;;yDAIF,aAAa;;;;;;;;;;;;;;;;;;;;0BAoB5C,YAAY;;;;uBAIf,YAAY;;;;;;;;;;;wBAWX,aAAa;;;;iBAIpB,qBAAqB;;;;;uBAKf,YAAY;;;;;;;;iBAQlB,QAAQ;kBACP,QAAQ;gBACV,aAAa;;;;gBAIb,qBAAqB;;;;;;;;;;;CAWpC,CAAC,aAAa,CACX,kBAAkB,CACd,kBAAkB,CAAC,SAAS,EAC5B,GAAG,CAAA;;uCAE4B,WAAW;;;;;qCAKb,qBAAqB;;SAEjD,CACJ,EACD,kBAAkB,CACd,kBAAkB,CAAC,OAAO,EAC1B,GAAG,CAAA;;gCAEqB,WAAW;;;SAGlC,CACJ,EACD,kBAAkB,CACd,kBAAkB,CAAC,KAAK,EACxB,GAAG,CAAA;;yCAE8B,qBAAqB;;;;uCAIvB,WAAW;;;;;yCAKT,qBAAqB;;SAErD,CACJ,EACD,aAAa,CACT,KAAK,CAAC,KAAK,EACX,GAAG,CAAA;;8BAEmB,iBAAiB,CAAC,KAAK,EAAE,IAAI,CAAC;;SAEnD,CACJ,CACJ,CAAC","sourcesContent":["import { css } from '@microsoft/fast-element';\nimport { White } from '@ni/nimble-tokens/dist/styledictionary/js/tokens';\nimport { display } from '../../utilities/style/display';\nimport {\n applicationBackgroundColor,\n bodyFont,\n bodyFontColor,\n bodyDisabledFontColor,\n borderHoverColor,\n borderWidth,\n controlHeight,\n iconSize,\n menuMinWidth,\n popupBorderColor,\n smallDelay,\n smallPadding,\n borderRgbPartialColor,\n mediumPadding,\n failColor,\n elevation2BoxShadow\n} from '../../theme-provider/design-tokens';\nimport { Theme } from '../../theme-provider/types';\nimport { appearanceBehavior } from '../../utilities/style/appearance';\nimport { hexToRgbaCssColor } from '../../utilities/style/colors';\nimport { focusVisible } from '../../utilities/style/focus';\nimport { themeBehavior } from '../../utilities/style/theme';\nimport { DropdownAppearance } from './types';\nimport { userSelectNone } from '../../utilities/style/user-select';\n\nexport const styles = css`\n ${display('inline-flex')}\n\n :host {\n color: ${bodyFontColor};\n font: ${bodyFont};\n height: ${controlHeight};\n position: relative;\n justify-content: center;\n ${userSelectNone}\n min-width: ${menuMinWidth};\n outline: none;\n vertical-align: top;\n --ni-private-hover-indicator-width: calc(${borderWidth} + 1px);\n --ni-private-focus-indicator-width: 1px;\n --ni-private-indicator-lines-gap: 1px;\n }\n\n :host::before {\n content: '';\n position: absolute;\n bottom: calc(${borderWidth} + var(--ni-private-indicator-lines-gap));\n width: 0px;\n height: 0px;\n justify-self: center;\n border-bottom: ${borderHoverColor}\n var(--ni-private-focus-indicator-width) solid;\n transition: width ${smallDelay} ease-in;\n }\n\n @media (prefers-reduced-motion) {\n :host::before {\n transition-duration: 0s;\n }\n }\n\n :host(${focusVisible})::before {\n width: calc(100% - 8px);\n }\n\n :host([error-visible]):before {\n border-bottom-color: ${failColor};\n }\n\n :host::after {\n content: '';\n position: absolute;\n bottom: calc(-1 * ${borderWidth});\n width: 0px;\n height: 0px;\n justify-self: center;\n border-bottom: ${borderHoverColor}\n var(--ni-private-hover-indicator-width) solid;\n transition: width ${smallDelay} ease-in;\n }\n\n @media (prefers-reduced-motion) {\n :host::after {\n transition-duration: 0s;\n }\n }\n\n :host(:hover)::after,\n :host(${focusVisible})::after {\n width: 100%;\n }\n\n :host([error-visible]):after {\n border-bottom-color: ${failColor};\n }\n\n :host([disabled]:hover)::after {\n width: 0px;\n }\n\n [part='start'] {\n display: none;\n }\n\n .control {\n align-items: center;\n cursor: pointer;\n display: flex;\n min-height: 100%;\n width: 100%;\n border: 0px solid rgba(${borderRgbPartialColor}, 0.3);\n background-color: transparent;\n padding: ${borderWidth};\n }\n\n :host([open]:not(:hover)) .control {\n border-bottom-color: ${borderHoverColor};\n }\n\n :host([disabled]) .control {\n cursor: default;\n color: ${bodyDisabledFontColor};\n border-color: rgba(${borderRgbPartialColor}, 0.1);\n }\n\n :host([error-visible]) .control,\n :host([error-visible][open]) .control,\n :host([error-visible][disabled]) .control {\n border-bottom-color: ${failColor};\n }\n\n .listbox {\n display: inline-flex;\n flex-direction: column;\n overflow-y: auto;\n width: 100%;\n --ni-private-listbox-padding: ${smallPadding};\n --ni-private-listbox-filter-height: 0px;\n --ni-private-listbox-loading-indicator-height: 0px;\n max-height: min(\n calc(\n ${smallPadding} + 2 * ${borderWidth} + ${controlHeight} * 10.5 +\n var(--ni-private-listbox-filter-height) +\n var(--ni-private-listbox-loading-indicator-height)\n ),\n calc(\n var(--ni-private-listbox-available-viewport-height) -\n ${smallPadding}\n )\n );\n box-shadow: ${elevation2BoxShadow};\n border: ${borderWidth} solid ${popupBorderColor};\n background-color: ${applicationBackgroundColor};\n }\n\n .listbox:has(.filter-field) {\n --ni-private-listbox-filter-height: ${controlHeight};\n }\n\n .listbox:has(.loading-container) {\n --ni-private-listbox-loading-indicator-height: ${controlHeight};\n }\n\n .listbox slot {\n display: block;\n background: transparent;\n padding: var(--ni-private-listbox-padding);\n }\n\n :host([open][position='above']) .listbox {\n border-bottom-left-radius: 0;\n border-bottom-right-radius: 0;\n }\n\n :host([open][position='below']) .listbox {\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n }\n\n :host([open][position='above']) .anchored-region {\n padding-bottom: ${smallPadding};\n }\n\n :host([open][position='below']) .anchored-region {\n padding-top: ${smallPadding};\n }\n\n .selected-value {\n flex: auto;\n font-family: inherit;\n text-align: start;\n white-space: nowrap;\n text-overflow: ellipsis;\n overflow: hidden;\n padding: 0px;\n padding-left: ${mediumPadding};\n }\n\n .selected-value[disabled]::placeholder {\n color: ${bodyDisabledFontColor};\n }\n\n .indicator {\n flex: none;\n margin-left: ${smallPadding};\n padding-right: 8px;\n display: flex;\n justify-content: center;\n align-items: center;\n }\n\n .indicator slot[name='indicator'] svg {\n width: ${iconSize};\n height: ${iconSize};\n fill: ${bodyFontColor};\n }\n\n :host([disabled]) .indicator slot[name='indicator'] svg {\n fill: ${bodyDisabledFontColor};\n }\n\n [part='end'] {\n margin-inline-start: auto;\n }\n\n ::slotted([role='option']),\n ::slotted(option) {\n flex: none;\n }\n`.withBehaviors(\n appearanceBehavior(\n DropdownAppearance.underline,\n css`\n .control {\n border-bottom-width: ${borderWidth};\n padding-bottom: 0;\n }\n\n :host([disabled]) .control {\n border-color: rgba(${borderRgbPartialColor}, 0.1);\n }\n `\n ),\n appearanceBehavior(\n DropdownAppearance.outline,\n css`\n .control {\n border-width: ${borderWidth};\n padding: 0;\n }\n `\n ),\n appearanceBehavior(\n DropdownAppearance.block,\n css`\n .control {\n background-color: rgba(${borderRgbPartialColor}, 0.1);\n }\n\n .control:focus-within {\n border-bottom-width: ${borderWidth};\n padding-bottom: 0;\n }\n\n :host([disabled]) .control {\n background-color: rgba(${borderRgbPartialColor}, 0.07);\n }\n `\n ),\n themeBehavior(\n Theme.color,\n css`\n .listbox slot {\n background: ${hexToRgbaCssColor(White, 0.15)};\n }\n `\n )\n);\n"]}
1
+ {"version":3,"file":"styles.js","sourceRoot":"","sources":["../../../../src/patterns/dropdown/styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,yBAAyB,CAAC;AAC9C,OAAO,EAAE,KAAK,EAAE,MAAM,kDAAkD,CAAC;AACzE,OAAO,EAAE,OAAO,EAAE,MAAM,+BAA+B,CAAC;AACxD,OAAO,EACH,0BAA0B,EAC1B,QAAQ,EACR,aAAa,EACb,qBAAqB,EACrB,gBAAgB,EAChB,WAAW,EACX,aAAa,EACb,QAAQ,EACR,YAAY,EACZ,gBAAgB,EAChB,UAAU,EACV,YAAY,EACZ,qBAAqB,EACrB,aAAa,EACb,SAAS,EACT,mBAAmB,EACtB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAEnE,kBAAkB;AAClB,MAAM,CAAC,MAAM,MAAM,GAAG,GAAG,CAAA;MACnB,OAAO,CAAC,aAAa,CAAC;;;iBAGX,aAAa;gBACd,QAAQ;kBACN,aAAa;;;UAGrB,cAAc;qBACH,YAAY;;;mDAGkB,WAAW;;;;;;;;uBAQvC,WAAW;;;;yBAIT,gBAAgB;;4BAEb,UAAU;;;;;;;;;YAS1B,YAAY;;;;;+BAKO,SAAS;;;;;;4BAMZ,WAAW;;;;yBAId,gBAAgB;;4BAEb,UAAU;;;;;;;;;;YAU1B,YAAY;;;;;+BAKO,SAAS;;;;;;;;;;;;;;;;;iCAiBP,qBAAqB;;mBAEnC,WAAW;;;;+BAIC,gBAAgB;;;;;iBAK9B,qBAAqB;6BACT,qBAAqB;;;;;;+BAMnB,SAAS;;;;;;;;;mDASW,YAAY;wCACvB,YAAY;;;;;;sBAM9B,WAAW;;kBAEf,aAAa;;;;;;;;;sBAST,mBAAmB;kBACvB,WAAW,UAAU,gBAAgB;4BAC3B,0BAA0B;;;;8CAIR,aAAa;;;;yDAIF,aAAa;;;;;;;;;;;;;;;;;;;;0BAoB5C,YAAY;;;;uBAIf,YAAY;;;;;;;;;;;wBAWX,aAAa;;;;iBAIpB,qBAAqB;;;;;uBAKf,YAAY;;;;;;;;iBAQlB,QAAQ;kBACP,QAAQ;gBACV,aAAa;;;;gBAIb,qBAAqB;;;;;;;;;;;CAWpC,CAAC,aAAa,CACX,kBAAkB,CACd,kBAAkB,CAAC,SAAS,EAC5B,GAAG,CAAA;;uCAE4B,WAAW;;;;;qCAKb,qBAAqB;;SAEjD,CACJ,EACD,kBAAkB,CACd,kBAAkB,CAAC,OAAO,EAC1B,GAAG,CAAA;;gCAEqB,WAAW;;;SAGlC,CACJ,EACD,kBAAkB,CACd,kBAAkB,CAAC,KAAK,EACxB,GAAG,CAAA;;yCAE8B,qBAAqB;;;;uCAIvB,WAAW;;;;;yCAKT,qBAAqB;;SAErD,CACJ,EACD,aAAa,CACT,KAAK,CAAC,KAAK,EACX,GAAG,CAAA;;8BAEmB,iBAAiB,CAAC,KAAK,EAAE,IAAI,CAAC;;SAEnD,CACJ,CACJ,CAAC","sourcesContent":["import { css } from '@microsoft/fast-element';\nimport { White } from '@ni/nimble-tokens/dist/styledictionary/js/tokens';\nimport { display } from '../../utilities/style/display';\nimport {\n applicationBackgroundColor,\n bodyFont,\n bodyFontColor,\n bodyDisabledFontColor,\n borderHoverColor,\n borderWidth,\n controlHeight,\n iconSize,\n menuMinWidth,\n popupBorderColor,\n smallDelay,\n smallPadding,\n borderRgbPartialColor,\n mediumPadding,\n failColor,\n elevation2BoxShadow\n} from '../../theme-provider/design-tokens';\nimport { Theme } from '../../theme-provider/types';\nimport { appearanceBehavior } from '../../utilities/style/appearance';\nimport { hexToRgbaCssColor } from '../../utilities/style/colors';\nimport { focusVisible } from '../../utilities/style/focus';\nimport { themeBehavior } from '../../utilities/style/theme';\nimport { DropdownAppearance } from './types';\nimport { userSelectNone } from '../../utilities/style/user-select';\n\n// prettier-ignore\nexport const styles = css`\n ${display('inline-flex')}\n\n :host {\n color: ${bodyFontColor};\n font: ${bodyFont};\n height: ${controlHeight};\n position: relative;\n justify-content: center;\n ${userSelectNone}\n min-width: ${menuMinWidth};\n outline: none;\n vertical-align: top;\n --ni-private-hover-indicator-width: calc(${borderWidth} + 1px);\n --ni-private-focus-indicator-width: 1px;\n --ni-private-indicator-lines-gap: 1px;\n }\n\n :host::before {\n content: '';\n position: absolute;\n bottom: calc(${borderWidth} + var(--ni-private-indicator-lines-gap));\n width: 0px;\n height: 0px;\n justify-self: center;\n border-bottom: ${borderHoverColor}\n var(--ni-private-focus-indicator-width) solid;\n transition: width ${smallDelay} ease-in;\n }\n\n @media (prefers-reduced-motion) {\n :host::before {\n transition-duration: 0s;\n }\n }\n\n :host(${focusVisible})::before {\n width: calc(100% - 8px);\n }\n\n :host([error-visible]):before {\n border-bottom-color: ${failColor};\n }\n\n :host::after {\n content: '';\n position: absolute;\n bottom: calc(-1 * ${borderWidth});\n width: 0px;\n height: 0px;\n justify-self: center;\n border-bottom: ${borderHoverColor}\n var(--ni-private-hover-indicator-width) solid;\n transition: width ${smallDelay} ease-in;\n }\n\n @media (prefers-reduced-motion) {\n :host::after {\n transition-duration: 0s;\n }\n }\n\n :host(:hover)::after,\n :host(${focusVisible})::after {\n width: 100%;\n }\n\n :host([error-visible]):after {\n border-bottom-color: ${failColor};\n }\n\n :host([disabled]:hover)::after {\n width: 0px;\n }\n\n [part='start'] {\n display: none;\n }\n\n .control {\n align-items: center;\n cursor: pointer;\n display: flex;\n min-height: 100%;\n width: 100%;\n border: 0px solid rgba(${borderRgbPartialColor}, 0.3);\n background-color: transparent;\n padding: ${borderWidth};\n }\n\n :host([open]:not(:hover)) .control {\n border-bottom-color: ${borderHoverColor};\n }\n\n :host([disabled]) .control {\n cursor: default;\n color: ${bodyDisabledFontColor};\n border-color: rgba(${borderRgbPartialColor}, 0.1);\n }\n\n :host([error-visible]) .control,\n :host([error-visible][open]) .control,\n :host([error-visible][disabled]) .control {\n border-bottom-color: ${failColor};\n }\n\n .listbox {\n display: inline-flex;\n flex-direction: column;\n overflow-y: auto;\n width: 100%;\n --ni-private-listbox-visible-option-count: 10.5;\n --ni-private-listbox-anchor-element-gap: ${smallPadding};\n --ni-private-listbox-padding: ${smallPadding};\n --ni-private-listbox-filter-height: 0px;\n --ni-private-listbox-loading-indicator-height: 0px;\n max-height: min(\n calc(\n var(--ni-private-listbox-anchor-element-gap) + \n 2 * ${borderWidth} + \n var(--ni-private-listbox-padding) +\n ${controlHeight} * var(--ni-private-listbox-visible-option-count) +\n var(--ni-private-listbox-filter-height) +\n var(--ni-private-listbox-loading-indicator-height)\n ),\n calc(\n var(--ni-private-listbox-available-viewport-height) - \n var(--ni-private-listbox-anchor-element-gap)\n )\n );\n box-shadow: ${elevation2BoxShadow};\n border: ${borderWidth} solid ${popupBorderColor};\n background-color: ${applicationBackgroundColor};\n }\n\n .listbox:has(.filter-field) {\n --ni-private-listbox-filter-height: ${controlHeight};\n }\n\n .listbox:has(.loading-container) {\n --ni-private-listbox-loading-indicator-height: ${controlHeight};\n }\n\n .listbox slot {\n display: block;\n background: transparent;\n padding: var(--ni-private-listbox-padding);\n }\n\n :host([open][position='above']) .listbox {\n border-bottom-left-radius: 0;\n border-bottom-right-radius: 0;\n }\n\n :host([open][position='below']) .listbox {\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n }\n\n :host([open][position='above']) .anchored-region {\n padding-bottom: ${smallPadding};\n }\n\n :host([open][position='below']) .anchored-region {\n padding-top: ${smallPadding};\n }\n\n .selected-value {\n flex: auto;\n font-family: inherit;\n text-align: start;\n white-space: nowrap;\n text-overflow: ellipsis;\n overflow: hidden;\n padding: 0px;\n padding-left: ${mediumPadding};\n }\n\n .selected-value[disabled]::placeholder {\n color: ${bodyDisabledFontColor};\n }\n\n .indicator {\n flex: none;\n margin-left: ${smallPadding};\n padding-right: 8px;\n display: flex;\n justify-content: center;\n align-items: center;\n }\n\n .indicator slot[name='indicator'] svg {\n width: ${iconSize};\n height: ${iconSize};\n fill: ${bodyFontColor};\n }\n\n :host([disabled]) .indicator slot[name='indicator'] svg {\n fill: ${bodyDisabledFontColor};\n }\n\n [part='end'] {\n margin-inline-start: auto;\n }\n\n ::slotted([role='option']),\n ::slotted(option) {\n flex: none;\n }\n`.withBehaviors(\n appearanceBehavior(\n DropdownAppearance.underline,\n css`\n .control {\n border-bottom-width: ${borderWidth};\n padding-bottom: 0;\n }\n\n :host([disabled]) .control {\n border-color: rgba(${borderRgbPartialColor}, 0.1);\n }\n `\n ),\n appearanceBehavior(\n DropdownAppearance.outline,\n css`\n .control {\n border-width: ${borderWidth};\n padding: 0;\n }\n `\n ),\n appearanceBehavior(\n DropdownAppearance.block,\n css`\n .control {\n background-color: rgba(${borderRgbPartialColor}, 0.1);\n }\n\n .control:focus-within {\n border-bottom-width: ${borderWidth};\n padding-bottom: 0;\n }\n\n :host([disabled]) .control {\n background-color: rgba(${borderRgbPartialColor}, 0.07);\n }\n `\n ),\n themeBehavior(\n Theme.color,\n css`\n .listbox slot {\n background: ${hexToRgbaCssColor(White, 0.15)};\n }\n `\n )\n);\n"]}
@@ -18,6 +18,12 @@ export declare class RichTextMentionListbox extends FoundationListbox {
18
18
  * @internal
19
19
  */
20
20
  region?: AnchoredRegion;
21
+ /**
22
+ * The space available in the viewport for the listbox when opened.
23
+ *
24
+ * @internal
25
+ */
26
+ availableViewportHeight: number;
21
27
  /**
22
28
  * @internal
23
29
  */
@@ -29,6 +35,12 @@ export declare class RichTextMentionListbox extends FoundationListbox {
29
35
  * @internal
30
36
  */
31
37
  filteredOptions: ListboxOption[];
38
+ /**
39
+ * Reference to the internal listbox element.
40
+ *
41
+ * @internal
42
+ */
43
+ listbox: HTMLDivElement;
32
44
  private anchorElement?;
33
45
  private regionNotifier?;
34
46
  private readonly anchorElementIntersectionObserver;
@@ -110,7 +122,6 @@ export declare class RichTextMentionListbox extends FoundationListbox {
110
122
  * Overrides: `Listbox.focusAndScrollOptionIntoView`
111
123
  */
112
124
  protected focusAndScrollOptionIntoView(): void;
113
- private emitMentionSelected;
114
125
  private setOpen;
115
126
  }
116
127
  export declare const richTextMentionListboxTag = "nimble-rich-text-mention-listbox";
@@ -11,6 +11,12 @@ import { diacriticInsensitiveStringNormalizer } from '../../utilities/models/str
11
11
  export class RichTextMentionListbox extends FoundationListbox {
12
12
  constructor() {
13
13
  super(...arguments);
14
+ /**
15
+ * The space available in the viewport for the listbox when opened.
16
+ *
17
+ * @internal
18
+ */
19
+ this.availableViewportHeight = 0;
14
20
  /**
15
21
  * @internal
16
22
  */
@@ -55,6 +61,8 @@ export class RichTextMentionListbox extends FoundationListbox {
55
61
  * @public
56
62
  */
57
63
  show(options) {
64
+ const listboxTop = options.anchorNode.getBoundingClientRect().bottom;
65
+ this.availableViewportHeight = Math.trunc(window.innerHeight - listboxTop);
58
66
  this.filter = options.filter;
59
67
  this.anchorElement = options.anchorNode;
60
68
  this.setOpen(true);
@@ -80,7 +88,8 @@ export class RichTextMentionListbox extends FoundationListbox {
80
88
  href: this.firstSelectedOption.value,
81
89
  displayName: this.firstSelectedOption.text
82
90
  };
83
- this.emitMentionSelected(mentionDetail);
91
+ this.$emit('mention-selected', mentionDetail);
92
+ this.setOpen(false);
84
93
  return true;
85
94
  }
86
95
  case keyEscape: {
@@ -147,7 +156,8 @@ export class RichTextMentionListbox extends FoundationListbox {
147
156
  href: capturedListOption.value,
148
157
  displayName: capturedListOption.text
149
158
  };
150
- this.emitMentionSelected(mentionDetail);
159
+ this.$emit('mention-selected', mentionDetail);
160
+ this.setOpen(false);
151
161
  return true;
152
162
  }
153
163
  /**
@@ -205,10 +215,6 @@ export class RichTextMentionListbox extends FoundationListbox {
205
215
  });
206
216
  }
207
217
  }
208
- emitMentionSelected(mentionDetail) {
209
- this.$emit('mention-selected', mentionDetail);
210
- this.setOpen(false);
211
- }
212
218
  setOpen(value) {
213
219
  this.open = value;
214
220
  }
@@ -219,6 +225,9 @@ __decorate([
219
225
  __decorate([
220
226
  observable
221
227
  ], RichTextMentionListbox.prototype, "region", void 0);
228
+ __decorate([
229
+ observable
230
+ ], RichTextMentionListbox.prototype, "availableViewportHeight", void 0);
222
231
  __decorate([
223
232
  observable
224
233
  ], RichTextMentionListbox.prototype, "anchorElement", void 0);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/rich-text/mention-listbox/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { Notifier, Observable, observable } from '@microsoft/fast-element';\nimport {\n DesignSystem,\n ListboxElement as FoundationListbox,\n ListboxOption\n} from '@microsoft/fast-foundation';\nimport { keyEnter, keyEscape, keyTab } from '@microsoft/fast-web-utilities';\nimport type { MentionDetail } from '../editor/types';\nimport { styles } from './styles';\nimport { template } from './template';\nimport type { AnchoredRegion } from '../../anchored-region';\nimport { diacriticInsensitiveStringNormalizer } from '../../utilities/models/string-normalizers';\nimport type { ListOption } from '../../list-option';\nimport type { MentionListboxShowOptions } from './types';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'nimble-rich-text-mention-listbox': RichTextMentionListbox;\n }\n}\n\n/**\n * A rich text mention listbox which acts as a popup for \"@mention\" support in editor\n */\nexport class RichTextMentionListbox extends FoundationListbox {\n /**\n * @internal\n */\n @observable\n public open?: boolean;\n\n /**\n * @internal\n */\n @observable\n public region?: AnchoredRegion;\n\n /**\n * @internal\n */\n public filter = '';\n\n /**\n * The collection of currently filtered options.\n * The approach is defined based on the `Combobox.filteredOptions` implementation.\n *\n * @internal\n */\n public filteredOptions: ListboxOption[] = [];\n\n @observable\n private anchorElement?: HTMLElement;\n\n private regionNotifier?: Notifier;\n\n private readonly anchorElementIntersectionObserver: IntersectionObserver = new IntersectionObserver(\n entries => {\n if (!entries[0]?.isIntersecting) {\n this.setOpen(false);\n }\n },\n { threshold: 1.0, root: document }\n );\n\n /**\n * @public\n */\n public close(): void {\n this.setOpen(false);\n }\n\n /**\n * The list of options.\n *\n * @public\n * @remarks\n * Overrides `Listbox.options`.\n */\n public override get options(): ListboxOption[] {\n Observable.track(this, 'options');\n return this.filteredOptions?.length ? this.filteredOptions : [];\n }\n\n public override set options(value: ListboxOption[]) {\n this._options = value;\n Observable.notify(this, 'options');\n }\n\n /**\n * Triggers when the mention plugin is activated upon pressing the `key`\n *\n * @public\n */\n public show(options: MentionListboxShowOptions): void {\n this.filter = options.filter;\n this.anchorElement = options.anchorNode;\n this.setOpen(true);\n this.filterOptions();\n }\n\n /**\n * Handle keydown actions for listbox navigation and selection.\n *\n * @param e - the keyboard event\n * @public\n */\n public override keydownHandler(event: KeyboardEvent): boolean {\n if (!this.open) {\n return false;\n }\n switch (event.key) {\n case keyTab:\n case keyEnter: {\n if (!this.hasSelectableOptions) {\n return false;\n }\n const mentionDetail: MentionDetail = {\n href: this.firstSelectedOption.value,\n displayName: this.firstSelectedOption.text\n };\n this.emitMentionSelected(mentionDetail);\n return true;\n }\n case keyEscape: {\n this.setOpen(false);\n return false;\n }\n default: {\n super.keydownHandler(event);\n return false;\n }\n }\n }\n\n /**\n * Filter available options by filter value.\n * The method is defined based on the `Combobox.filterOptions` and `Combobox.inputHandler` implementation.\n *\n * @internal\n */\n public filterOptions(): void {\n if (!this.filter) {\n this.filteredOptions = this._options;\n } else {\n const normalizedFilter = diacriticInsensitiveStringNormalizer(\n this.filter\n );\n this.filteredOptions = this._options.filter(o => diacriticInsensitiveStringNormalizer(o.text).includes(\n normalizedFilter\n ));\n }\n\n this._options.forEach(o => {\n o.hidden = !this.filteredOptions.includes(o);\n });\n\n if (this.filteredOptions.length) {\n this.selectedOptions = [this.filteredOptions[0]!];\n this.selectedIndex = this.options.indexOf(this.firstSelectedOption);\n } else {\n this.selectedOptions = [];\n this.selectedIndex = -1;\n }\n }\n\n /**\n * Synchronize the form-associated proxy and update the value property of the element.\n *\n * @param prev - the previous collection of slotted option elements\n * @param next - the next collection of slotted option elements\n *\n * @internal\n */\n public override slottedOptionsChanged(\n prev: Element[] | undefined,\n next: Element[]\n ): void {\n super.slottedOptionsChanged(prev, next);\n this.filterOptions();\n }\n\n /**\n * Triggers the `suggestionProps` command to notify the tiptap editor to select the option.\n * The method is defined based on the `Listbox.clickHandler` implementation.\n *\n * @internal\n */\n public override clickHandler(e: MouseEvent): boolean {\n const capturedElement = (e.target as HTMLElement).closest(\n 'option,[role=option]'\n );\n\n const capturedListOption = capturedElement as ListOption | null;\n\n if (!capturedListOption || capturedListOption.disabled) {\n return false;\n }\n const mentionDetail: MentionDetail = {\n href: capturedListOption.value,\n displayName: capturedListOption.text\n };\n this.emitMentionSelected(mentionDetail);\n return true;\n }\n\n /**\n * Observes the anchor element using intersection observer.\n * Once the anchor element intersects, the anchor region will be closed.\n *\n * @internal\n */\n public anchorElementChanged(prev: HTMLElement, next: HTMLElement): void {\n if (prev) {\n this.anchorElementIntersectionObserver.unobserve(prev);\n }\n if (this.region && this.anchorElement) {\n this.region.anchorElement = this.anchorElement;\n this.region.update();\n this.anchorElementIntersectionObserver.observe(next);\n }\n }\n\n /**\n * Observes the anchor region.\n *\n * @internal\n */\n public regionChanged(): void {\n if (this.regionNotifier) {\n this.regionNotifier.unsubscribe(this);\n }\n this.regionNotifier = Observable.getNotifier(this.region);\n this.regionNotifier.subscribe(this);\n }\n\n /**\n * Handles the events of the anchored region.\n * Repositions the listbox scroll bar when the `initialLayoutComplete` event is triggered.\n * Other events will be passed to the base class.\n *\n * @internal\n */\n public override handleChange(source: unknown, args: string): void {\n super.handleChange(source, args);\n if (args === 'initialLayoutComplete') {\n this.focusAndScrollOptionIntoView();\n }\n }\n\n /**\n * Focus the control and scroll the first selected option into view.\n *\n * @internal\n * @remarks\n * Overrides: `Listbox.focusAndScrollOptionIntoView`\n */\n protected override focusAndScrollOptionIntoView(): void {\n if (this.open && this.firstSelectedOption) {\n requestAnimationFrame(() => {\n this.firstSelectedOption?.scrollIntoView({ block: 'nearest' });\n });\n }\n }\n\n private emitMentionSelected(mentionDetail: MentionDetail): void {\n this.$emit('mention-selected', mentionDetail);\n this.setOpen(false);\n }\n\n private setOpen(value: boolean): void {\n this.open = value;\n }\n}\n\nconst nimbleRichTextMentionListbox = RichTextMentionListbox.compose({\n baseName: 'rich-text-mention-listbox',\n template,\n styles\n});\n\nDesignSystem.getOrCreate()\n .withPrefix('nimble')\n .register(nimbleRichTextMentionListbox());\nexport const richTextMentionListboxTag = 'nimble-rich-text-mention-listbox';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/rich-text/mention-listbox/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { Notifier, Observable, observable } from '@microsoft/fast-element';\nimport {\n DesignSystem,\n ListboxElement as FoundationListbox,\n ListboxOption\n} from '@microsoft/fast-foundation';\nimport { keyEnter, keyEscape, keyTab } from '@microsoft/fast-web-utilities';\nimport type { MentionDetail } from '../editor/types';\nimport { styles } from './styles';\nimport { template } from './template';\nimport type { AnchoredRegion } from '../../anchored-region';\nimport { diacriticInsensitiveStringNormalizer } from '../../utilities/models/string-normalizers';\nimport type { ListOption } from '../../list-option';\nimport type { MentionListboxShowOptions } from './types';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'nimble-rich-text-mention-listbox': RichTextMentionListbox;\n }\n}\n\n/**\n * A rich text mention listbox which acts as a popup for \"@mention\" support in editor\n */\nexport class RichTextMentionListbox extends FoundationListbox {\n /**\n * @internal\n */\n @observable\n public open?: boolean;\n\n /**\n * @internal\n */\n @observable\n public region?: AnchoredRegion;\n\n /**\n * The space available in the viewport for the listbox when opened.\n *\n * @internal\n */\n @observable\n public availableViewportHeight = 0;\n\n /**\n * @internal\n */\n public filter = '';\n\n /**\n * The collection of currently filtered options.\n * The approach is defined based on the `Combobox.filteredOptions` implementation.\n *\n * @internal\n */\n public filteredOptions: ListboxOption[] = [];\n\n /**\n * Reference to the internal listbox element.\n *\n * @internal\n */\n public listbox!: HTMLDivElement;\n\n @observable\n private anchorElement?: HTMLElement;\n\n private regionNotifier?: Notifier;\n\n private readonly anchorElementIntersectionObserver: IntersectionObserver = new IntersectionObserver(\n entries => {\n if (!entries[0]?.isIntersecting) {\n this.setOpen(false);\n }\n },\n { threshold: 1.0, root: document }\n );\n\n /**\n * @public\n */\n public close(): void {\n this.setOpen(false);\n }\n\n /**\n * The list of options.\n *\n * @public\n * @remarks\n * Overrides `Listbox.options`.\n */\n public override get options(): ListboxOption[] {\n Observable.track(this, 'options');\n return this.filteredOptions?.length ? this.filteredOptions : [];\n }\n\n public override set options(value: ListboxOption[]) {\n this._options = value;\n Observable.notify(this, 'options');\n }\n\n /**\n * Triggers when the mention plugin is activated upon pressing the `key`\n *\n * @public\n */\n public show(options: MentionListboxShowOptions): void {\n const listboxTop = options.anchorNode.getBoundingClientRect().bottom;\n this.availableViewportHeight = Math.trunc(\n window.innerHeight - listboxTop\n );\n this.filter = options.filter;\n this.anchorElement = options.anchorNode;\n this.setOpen(true);\n this.filterOptions();\n }\n\n /**\n * Handle keydown actions for listbox navigation and selection.\n *\n * @param e - the keyboard event\n * @public\n */\n public override keydownHandler(event: KeyboardEvent): boolean {\n if (!this.open) {\n return false;\n }\n switch (event.key) {\n case keyTab:\n case keyEnter: {\n if (!this.hasSelectableOptions) {\n return false;\n }\n const mentionDetail: MentionDetail = {\n href: this.firstSelectedOption.value,\n displayName: this.firstSelectedOption.text\n };\n this.$emit('mention-selected', mentionDetail);\n this.setOpen(false);\n return true;\n }\n case keyEscape: {\n this.setOpen(false);\n return false;\n }\n default: {\n super.keydownHandler(event);\n return false;\n }\n }\n }\n\n /**\n * Filter available options by filter value.\n * The method is defined based on the `Combobox.filterOptions` and `Combobox.inputHandler` implementation.\n *\n * @internal\n */\n public filterOptions(): void {\n if (!this.filter) {\n this.filteredOptions = this._options;\n } else {\n const normalizedFilter = diacriticInsensitiveStringNormalizer(\n this.filter\n );\n this.filteredOptions = this._options.filter(o => diacriticInsensitiveStringNormalizer(o.text).includes(\n normalizedFilter\n ));\n }\n\n this._options.forEach(o => {\n o.hidden = !this.filteredOptions.includes(o);\n });\n\n if (this.filteredOptions.length) {\n this.selectedOptions = [this.filteredOptions[0]!];\n this.selectedIndex = this.options.indexOf(this.firstSelectedOption);\n } else {\n this.selectedOptions = [];\n this.selectedIndex = -1;\n }\n }\n\n /**\n * Synchronize the form-associated proxy and update the value property of the element.\n *\n * @param prev - the previous collection of slotted option elements\n * @param next - the next collection of slotted option elements\n *\n * @internal\n */\n public override slottedOptionsChanged(\n prev: Element[] | undefined,\n next: Element[]\n ): void {\n super.slottedOptionsChanged(prev, next);\n this.filterOptions();\n }\n\n /**\n * Triggers the `suggestionProps` command to notify the tiptap editor to select the option.\n * The method is defined based on the `Listbox.clickHandler` implementation.\n *\n * @internal\n */\n public override clickHandler(e: MouseEvent): boolean {\n const capturedElement = (e.target as HTMLElement).closest(\n 'option,[role=option]'\n );\n\n const capturedListOption = capturedElement as ListOption | null;\n\n if (!capturedListOption || capturedListOption.disabled) {\n return false;\n }\n const mentionDetail: MentionDetail = {\n href: capturedListOption.value,\n displayName: capturedListOption.text\n };\n this.$emit('mention-selected', mentionDetail);\n this.setOpen(false);\n return true;\n }\n\n /**\n * Observes the anchor element using intersection observer.\n * Once the anchor element intersects, the anchor region will be closed.\n *\n * @internal\n */\n public anchorElementChanged(prev: HTMLElement, next: HTMLElement): void {\n if (prev) {\n this.anchorElementIntersectionObserver.unobserve(prev);\n }\n if (this.region && this.anchorElement) {\n this.region.anchorElement = this.anchorElement;\n this.region.update();\n this.anchorElementIntersectionObserver.observe(next);\n }\n }\n\n /**\n * Observes the anchor region.\n *\n * @internal\n */\n public regionChanged(): void {\n if (this.regionNotifier) {\n this.regionNotifier.unsubscribe(this);\n }\n this.regionNotifier = Observable.getNotifier(this.region);\n this.regionNotifier.subscribe(this);\n }\n\n /**\n * Handles the events of the anchored region.\n * Repositions the listbox scroll bar when the `initialLayoutComplete` event is triggered.\n * Other events will be passed to the base class.\n *\n * @internal\n */\n public override handleChange(source: unknown, args: string): void {\n super.handleChange(source, args);\n if (args === 'initialLayoutComplete') {\n this.focusAndScrollOptionIntoView();\n }\n }\n\n /**\n * Focus the control and scroll the first selected option into view.\n *\n * @internal\n * @remarks\n * Overrides: `Listbox.focusAndScrollOptionIntoView`\n */\n protected override focusAndScrollOptionIntoView(): void {\n if (this.open && this.firstSelectedOption) {\n requestAnimationFrame(() => {\n this.firstSelectedOption?.scrollIntoView({ block: 'nearest' });\n });\n }\n }\n\n private setOpen(value: boolean): void {\n this.open = value;\n }\n}\n\nconst nimbleRichTextMentionListbox = RichTextMentionListbox.compose({\n baseName: 'rich-text-mention-listbox',\n template,\n styles\n});\n\nDesignSystem.getOrCreate()\n .withPrefix('nimble')\n .register(nimbleRichTextMentionListbox());\nexport const richTextMentionListboxTag = 'nimble-rich-text-mention-listbox';\n"]}
@@ -1,7 +1,7 @@
1
1
  import { css } from '@microsoft/fast-element';
2
2
  import { styles as dropdownStyles } from '../../patterns/dropdown/styles';
3
3
  import { focusVisible } from '../../utilities/style/focus';
4
- import { controlHeight, menuMinWidth } from '../../theme-provider/design-tokens';
4
+ import { menuMinWidth } from '../../theme-provider/design-tokens';
5
5
  export const styles = css `
6
6
  ${dropdownStyles}
7
7
 
@@ -15,8 +15,9 @@ export const styles = css `
15
15
  }
16
16
 
17
17
  .listbox {
18
+ --ni-private-listbox-visible-option-count: 5.5;
19
+ --ni-private-listbox-anchor-element-gap: 0px;
18
20
  min-width: ${menuMinWidth};
19
- max-height: calc(5.5 * ${controlHeight});
20
21
  }
21
22
  `;
22
23
  //# sourceMappingURL=styles.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"styles.js","sourceRoot":"","sources":["../../../../src/rich-text/mention-listbox/styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,yBAAyB,CAAC;AAC9C,OAAO,EAAE,MAAM,IAAI,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EACH,aAAa,EACb,YAAY,EACf,MAAM,oCAAoC,CAAC;AAE5C,MAAM,CAAC,MAAM,MAAM,GAAG,GAAG,CAAA;MACnB,cAAc;;;;;;;YAOR,YAAY;;;;;qBAKH,YAAY;iCACA,aAAa;;CAE7C,CAAC","sourcesContent":["import { css } from '@microsoft/fast-element';\nimport { styles as dropdownStyles } from '../../patterns/dropdown/styles';\nimport { focusVisible } from '../../utilities/style/focus';\nimport {\n controlHeight,\n menuMinWidth\n} from '../../theme-provider/design-tokens';\n\nexport const styles = css`\n ${dropdownStyles}\n\n :host {\n height: auto;\n }\n\n :host(:hover)::after,\n :host(${focusVisible})::after {\n width: auto;\n }\n\n .listbox {\n min-width: ${menuMinWidth};\n max-height: calc(5.5 * ${controlHeight});\n }\n`;\n"]}
1
+ {"version":3,"file":"styles.js","sourceRoot":"","sources":["../../../../src/rich-text/mention-listbox/styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,yBAAyB,CAAC;AAC9C,OAAO,EAAE,MAAM,IAAI,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAElE,MAAM,CAAC,MAAM,MAAM,GAAG,GAAG,CAAA;MACnB,cAAc;;;;;;;YAOR,YAAY;;;;;;;qBAOH,YAAY;;CAEhC,CAAC","sourcesContent":["import { css } from '@microsoft/fast-element';\nimport { styles as dropdownStyles } from '../../patterns/dropdown/styles';\nimport { focusVisible } from '../../utilities/style/focus';\nimport { menuMinWidth } from '../../theme-provider/design-tokens';\n\nexport const styles = css`\n ${dropdownStyles}\n\n :host {\n height: auto;\n }\n\n :host(:hover)::after,\n :host(${focusVisible})::after {\n width: auto;\n }\n\n .listbox {\n --ni-private-listbox-visible-option-count: 5.5;\n --ni-private-listbox-anchor-element-gap: 0px;\n min-width: ${menuMinWidth};\n }\n`;\n"]}
@@ -21,6 +21,8 @@ export const template = html `
21
21
  role="listbox"
22
22
  @click="${(x, c) => x.clickHandler(c.event)}"
23
23
  ?disabled="${x => x.disabled}"
24
+ style="--ni-private-listbox-available-viewport-height: ${x => x.availableViewportHeight}px;"
25
+ ${ref('listbox')}
24
26
  >
25
27
  <slot name="option"
26
28
  ${slotted({ filter: (n) => n instanceof HTMLElement && Listbox.slottedOptionFilter(n), flatten: true, property: 'slottedOptions' })}
@@ -1 +1 @@
1
- {"version":3,"file":"template.js","sourceRoot":"","sources":["../../../../src/rich-text/mention-listbox/template.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAC;AAErD,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE1D,kBAAkB;AAClB,MAAM,CAAC,MAAM,QAAQ,GAAG,IAAI,CAAwB;;WAEzC,iBAAiB;cACd,GAAG,CAAC,QAAQ,CAAC;;;;;;;;;uBASJ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI;;;;;0BAKT,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,KAAmB,CAAC;6BAC5C,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ;;;sBAGtB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC,CAAO,EAAE,EAAE,CAAC,CAAC,YAAY,WAAW,IAAI,OAAO,CAAC,mBAAmB,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,gBAAgB,EAAE,CAAC;;;;YAIjJ,iBAAiB;;CAE5B,CAAC","sourcesContent":["import { html, ref, slotted } from '@microsoft/fast-element';\nimport { Listbox } from '@microsoft/fast-foundation';\nimport type { RichTextMentionListbox } from '.';\nimport { anchoredRegionTag } from '../../anchored-region';\n\n// prettier-ignore\nexport const template = html<RichTextMentionListbox>`\n <template>\n <${anchoredRegionTag}\n ${ref('region')}\n class=\"anchored-region\"\n fixed-placement\n auto-update-mode=\"auto\"\n vertical-default-position=\"bottom\"\n vertical-positioning-mode=\"locktodefault\"\n horizontal-default-position=\"center\"\n horizontal-positioning-mode=\"locktodefault\"\n horizontal-scaling=\"anchor\"\n ?hidden=\"${x => !x.open}\">\n <div\n class=\"listbox\"\n part=\"listbox\"\n role=\"listbox\"\n @click=\"${(x, c) => x.clickHandler(c.event as MouseEvent)}\"\n ?disabled=\"${x => x.disabled}\"\n >\n <slot name=\"option\"\n ${slotted({ filter: (n: Node) => n instanceof HTMLElement && Listbox.slottedOptionFilter(n), flatten: true, property: 'slottedOptions' })}\n >\n </slot>\n </div>\n </${anchoredRegionTag}>\n </template>\n`;\n"]}
1
+ {"version":3,"file":"template.js","sourceRoot":"","sources":["../../../../src/rich-text/mention-listbox/template.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAC;AAErD,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE1D,kBAAkB;AAClB,MAAM,CAAC,MAAM,QAAQ,GAAG,IAAI,CAAwB;;WAEzC,iBAAiB;cACd,GAAG,CAAC,QAAQ,CAAC;;;;;;;;;uBASJ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI;;;;;0BAKT,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,KAAmB,CAAC;6BAC5C,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ;yEAC6B,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,uBAAuB;kBACrF,GAAG,CAAC,SAAS,CAAC;;;sBAGV,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC,CAAO,EAAE,EAAE,CAAC,CAAC,YAAY,WAAW,IAAI,OAAO,CAAC,mBAAmB,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,gBAAgB,EAAE,CAAC;;;;YAIjJ,iBAAiB;;CAE5B,CAAC","sourcesContent":["import { html, ref, slotted } from '@microsoft/fast-element';\nimport { Listbox } from '@microsoft/fast-foundation';\nimport type { RichTextMentionListbox } from '.';\nimport { anchoredRegionTag } from '../../anchored-region';\n\n// prettier-ignore\nexport const template = html<RichTextMentionListbox>`\n <template>\n <${anchoredRegionTag}\n ${ref('region')}\n class=\"anchored-region\"\n fixed-placement\n auto-update-mode=\"auto\"\n vertical-default-position=\"bottom\"\n vertical-positioning-mode=\"locktodefault\"\n horizontal-default-position=\"center\"\n horizontal-positioning-mode=\"locktodefault\"\n horizontal-scaling=\"anchor\"\n ?hidden=\"${x => !x.open}\">\n <div\n class=\"listbox\"\n part=\"listbox\"\n role=\"listbox\"\n @click=\"${(x, c) => x.clickHandler(c.event as MouseEvent)}\"\n ?disabled=\"${x => x.disabled}\"\n style=\"--ni-private-listbox-available-viewport-height: ${x => x.availableViewportHeight}px;\"\n ${ref('listbox')}\n >\n <slot name=\"option\"\n ${slotted({ filter: (n: Node) => n instanceof HTMLElement && Listbox.slottedOptionFilter(n), flatten: true, property: 'slottedOptions' })}\n >\n </slot>\n </div>\n </${anchoredRegionTag}>\n </template>\n`;\n"]}
@@ -101,7 +101,7 @@ export class Select extends FormAssociatedSelect {
101
101
  }
102
102
  newValue = this.firstSelectedOption?.value ?? newValue;
103
103
  }
104
- if (prev !== newValue && !(this.open && this.selectedIndex < 0)) {
104
+ if (prev !== newValue) {
105
105
  this._value = newValue;
106
106
  super.valueChanged(prev, newValue);
107
107
  Observable.notify(this, 'value');
@@ -190,12 +190,12 @@ export class Select extends FormAssociatedSelect {
190
190
  }
191
191
  const previousSelectedIndex = this.selectedIndex;
192
192
  super.clickHandler(e);
193
- this.open = this.collapsible && !this.open;
194
- if (!this.open
193
+ if (this.open
195
194
  && this.selectedIndex !== previousSelectedIndex
196
195
  && optionClicked) {
197
196
  this.updateValue(true);
198
197
  }
198
+ this.open = this.collapsible && !this.open;
199
199
  }
200
200
  /**
201
201
  * Updates the value when an option's value changes.
@@ -378,6 +378,7 @@ export class Select extends FormAssociatedSelect {
378
378
  return true;
379
379
  }
380
380
  let currentActiveIndex = this.openActiveIndex ?? this.selectedIndex;
381
+ let commitValueThenClose = false;
381
382
  switch (key) {
382
383
  case keySpace: {
383
384
  // when dropdown is open allow user to enter a space for filter text
@@ -404,8 +405,13 @@ export class Select extends FormAssociatedSelect {
404
405
  || this.filteredOptions.every(o => o.disabled)) {
405
406
  return false;
406
407
  }
407
- this.open = !this.open;
408
- if (!this.open) {
408
+ if (this.open) {
409
+ commitValueThenClose = true;
410
+ }
411
+ else {
412
+ this.open = true;
413
+ }
414
+ if (commitValueThenClose) {
409
415
  this.focus();
410
416
  }
411
417
  break;
@@ -431,11 +437,16 @@ export class Select extends FormAssociatedSelect {
431
437
  break;
432
438
  }
433
439
  }
434
- if (!this.open && this.selectedIndex !== currentActiveIndex) {
435
- this.selectedIndex = currentActiveIndex;
440
+ if (!this.open || commitValueThenClose) {
441
+ if (this.selectedIndex !== currentActiveIndex) {
442
+ this.selectedIndex = currentActiveIndex;
443
+ }
444
+ if (initialSelectedIndex !== this.selectedIndex) {
445
+ this.updateValue(true);
446
+ }
436
447
  }
437
- if (!this.open && initialSelectedIndex !== this.selectedIndex) {
438
- this.updateValue(true);
448
+ if (commitValueThenClose) {
449
+ this.open = false;
439
450
  }
440
451
  return !(key === keyArrowDown || key === keyArrowUp);
441
452
  }