Skip to content

Commit 6a6fc3f

Browse files
authored
Fix select option overflow (#93)
1 parent 9546769 commit 6a6fc3f

File tree

3 files changed

+94
-27
lines changed

3 files changed

+94
-27
lines changed

docs/Examples/Select.example.purs

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,16 @@ module Lumi.Components.Examples.Select where
33
import Prelude
44

55
import Data.Array (filter)
6+
import Data.Array as Array
67
import Data.Maybe (Maybe(..), fromMaybe)
78
import Data.String (Pattern(..), contains, toLower)
89
import Effect.Aff (Milliseconds(..), delay)
910
import Lumi.Components.Column (column, column_)
11+
import Lumi.Components.Example (example)
1012
import Lumi.Components.Input as Input
1113
import Lumi.Components.LabeledField (labeledField, RequiredField(..))
1214
import Lumi.Components.Select (asyncMultiSelect, asyncSingleSelect, multiSelect, singleSelect)
1315
import Lumi.Components.Text (h2_)
14-
import Lumi.Components.Example (example)
1516
import React.Basic (Component, JSX, createComponent, make)
1617
import React.Basic.DOM (css)
1718
import React.Basic.DOM as R
@@ -191,4 +192,36 @@ docs = unit # make component { initialState, render }
191192
]
192193
}
193194

195+
, h2_ "Truncating long values"
196+
, example $
197+
column
198+
{ style: css { alignSelf: "stretch", maxWidth: "300px" }
199+
, children:
200+
[ let
201+
options =
202+
[ "80104 Somestreet Rd Ste 1124, San Diego, California, United States"
203+
, "1211 Blah blah Blvd, Charlotrte, North Carolina, United States"
204+
, "3031 Fall Ave, Colorado Springs, Colorado, United States"
205+
]
206+
in
207+
singleSelect
208+
{ value: Array.head options
209+
, options
210+
, optionSort: Nothing
211+
, onChange: mempty
212+
, className: ""
213+
, style: css {}
214+
, searchable: true
215+
, id: ""
216+
, name: ""
217+
, noResultsText: "No results"
218+
, placeholder: "Select a value..."
219+
, disabled
220+
, loading: false
221+
, optionRenderer: R.text
222+
, toSelectOption: \a -> { value: a, label: a }
223+
}
224+
]
225+
}
226+
194227
]

src/Lumi/Components/NativeSelect.purs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ module Lumi.Components.NativeSelect where
33
import Prelude
44

55
import Color (cssStringHSLA)
6-
import Data.Maybe (Maybe(..))
6+
import Data.Foldable (find)
7+
import Data.Maybe (Maybe(..), fromMaybe)
78
import Data.Nullable (Nullable, toNullable)
89
import Effect.Uncurried (mkEffectFn1)
910
import JSS (JSS, important, jss)
@@ -56,6 +57,10 @@ nativeSelect = makeStateless component $ lumiSelectElement <<< mapProps
5657
, required: props.required
5758
, style: props.style
5859
, value: props.value
60+
, title:
61+
fromMaybe props.placeholder do
62+
selected <- props.options # find \o -> o.value == props.value
63+
pure selected.label
5964
}
6065

6166
defaults :: NativeSelectProps
@@ -84,6 +89,7 @@ styles = jss
8489
, backgroundSize: "10px 5px"
8590
, cursor: "pointer"
8691
, display: "inline-block"
92+
, textOverflow: "ellipsis"
8793
, "&:-moz-focusring":
8894
{ color: "transparent"
8995
, textShadow: "0 0 0 " <> cssStringHSLA colors.black

src/Lumi/Components/Select.purs

Lines changed: 53 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,10 @@ select = makeStateless component render
269269
lumiSelectInputSelectedValueElement
270270
{ key: "lumi-select-selected-value-" <> (props.toSelectOption value).value
271271
, children:
272-
[ props.optionRenderer value
272+
[ lumiSelectInputSelectedValueTextElement
273+
{ children: [ props.optionRenderer value ]
274+
, title: (props.toSelectOption value).label
275+
}
273276
, lumiSelectClearIconElement
274277
{ key: "--createElementKeyed-shouldnt-require-this--"
275278
, children: Icon.icon_ Icon.Remove
@@ -339,13 +342,17 @@ select = makeStateless component render
339342
}
340343
]
341344
renderOptions options_ = options_ `flip Array.mapWithIndex` \index option ->
342-
lumiSelectOptionElement
343-
{ key: "lumi-select-menu-option-" <> (props.toSelectOption option).value
344-
, "data-focus": maybe false (_ == index) selectState.focusedIndex
345-
, children: props.optionRenderer option
346-
, onClick: capture_ do
347-
selectState.addSelectedOption option
348-
}
345+
let
346+
{ label, value } = props.toSelectOption option
347+
in
348+
lumiSelectOptionElement
349+
{ key: "lumi-select-menu-option-" <> value
350+
, "data-focus": maybe false (_ == index) selectState.focusedIndex
351+
, children: props.optionRenderer option
352+
, title: label
353+
, onClick: capture_ do
354+
selectState.addSelectedOption option
355+
}
349356

350357
lumiSelectElement =
351358
element (R.unsafeCreateDOMComponent "lumi-select")
@@ -361,6 +368,8 @@ select = makeStateless component render
361368
element (R.unsafeCreateDOMComponent "lumi-select-input-selected-values")
362369
lumiSelectInputSelectedValueElement =
363370
elementKeyed (R.unsafeCreateDOMComponent "lumi-select-input-selected-value")
371+
lumiSelectInputSelectedValueTextElement =
372+
element (R.unsafeCreateDOMComponent "lumi-select-input-selected-value-text")
364373
lumiSelectClearIconElement =
365374
element (R.unsafeCreateDOMComponent "lumi-select-clear-icon")
366375
lumiSelectMenuAnchorElement =
@@ -394,18 +403,16 @@ styles = jss
394403

395404
, "& lumi-select-input":
396405
{ extend: lumiInputStyles
397-
, position: "relative" -- for placeholder
398406
, display: "flex"
399407
, flexFlow: "row"
408+
, flex: "0 0 100%"
400409
, minHeight: "32px" -- input height (-8px from standard input sizing to account for select wrapper)
401410
, lineHeight: "32px"
402411
, "@media (min-width: 860px)":
403412
{ minHeight: "24px"
404413
, lineHeight: "24px"
405414
, backgroundPositionY: "12px"
406415
}
407-
, minWidth: "200px"
408-
, maxWidth: "100%"
409416
, backgroundImage: "url(\"data:image/svg+xml;charset=utf8,%3C?xml version='1.0' encoding='UTF-8'?%3E%3Csvg width='11px' height='5px' viewBox='0 0 11 5' version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'%3E%3C!-- Generator: Sketch 49.1 (51147) - http://www.bohemiancoding.com/sketch --%3E%3Ctitle%3ESlice 1%3C/title%3E%3Cdesc%3ECreated with Sketch.%3C/desc%3E%3Cdefs%3E%3Cpath d='M5.417,3.519 C5.797,3.187 6.307,2.733 6.912,2.185 L6.974,2.129 C7.70584693,1.46645784 8.43485361,0.800785071 9.161,0.132 C9.29247374,0.0108869595 9.47857352,-0.0308857001 9.64919735,0.0224173781 C9.81982119,0.0757204563 9.94904726,0.216001266 9.98819736,0.390417384 C10.0273475,0.564833501 9.97047374,0.746886966 9.839,0.868 C9.11068658,1.53896706 8.37934578,2.20664054 7.645,2.871 L7.583,2.927 C5.376,4.922 5.287,5 5,5 C4.713,5 4.624,4.922 2.417,2.927 L2.355,2.871 C1.62081041,2.20646869 0.889470368,1.5387959 0.161,0.868 C-0.0422407879,0.68077547 -0.0552245302,0.364240788 0.132,0.161 C0.31922453,-0.0422407879 0.635759212,-0.0552245302 0.839,0.132 C1.5649901,0.800955473 2.29399753,1.46662893 3.026,2.129 L3.088,2.185 C3.693,2.733 4.203,3.187 4.583,3.519 C4.75,3.665 4.89,3.785 5,3.877 C5.11,3.785 5.25,3.665 5.417,3.519 Z' id='path-1'%3E%3C/path%3E%3C/defs%3E%3Cg id='Page-1' stroke='none' stroke-width='1' fill='none' fill-rule='evenodd'%3E%3Cg id='arrow-down'%3E%3Cg id='a-link' fill='%2342413F' fill-rule='nonzero'%3E%3Cpath d='M5.417,3.519 C5.797,3.187 6.307,2.733 6.912,2.185 L6.974,2.129 C7.70584693,1.46645784 8.43485361,0.800785071 9.161,0.132 C9.29247374,0.0108869595 9.47857352,-0.0308857001 9.64919735,0.0224173781 C9.81982119,0.0757204563 9.94904726,0.216001266 9.98819736,0.390417384 C10.0273475,0.564833501 9.97047374,0.746886966 9.839,0.868 C9.11068658,1.53896706 8.37934578,2.20664054 7.645,2.871 L7.583,2.927 C5.376,4.922 5.287,5 5,5 C4.713,5 4.624,4.922 2.417,2.927 L2.355,2.871 C1.62081041,2.20646869 0.889470368,1.5387959 0.161,0.868 C-0.0422407879,0.68077547 -0.0552245302,0.364240788 0.132,0.161 C0.31922453,-0.0422407879 0.635759212,-0.0552245302 0.839,0.132 C1.5649901,0.800955473 2.29399753,1.46662893 3.026,2.129 L3.088,2.185 C3.693,2.733 4.203,3.187 4.583,3.519 C4.75,3.665 4.89,3.785 5,3.877 C5.11,3.785 5.25,3.665 5.417,3.519 Z' id='a'%3E%3C/path%3E%3C/g%3E%3Cg id='Clipped'%3E%3Cmask id='mask-2' fill='white'%3E%3Cuse xlink:href='%23path-1'%3E%3C/use%3E%3C/mask%3E%3Cg id='a'%3E%3C/g%3E%3Cg id='Group' mask='url(%23mask-2)' fill='%23292827' fill-rule='nonzero'%3E%3Cg transform='translate(-5.000000, -8.000000)' id='Shape'%3E%3Cpolygon points='0 0 20 0 20 20 0 20'%3E%3C/polygon%3E%3C/g%3E%3C/g%3E%3C/g%3E%3C/g%3E%3C/g%3E%3C/svg%3E\")"
410417
, backgroundRepeat: "no-repeat"
411418
, backgroundPositionY: "16px"
@@ -415,27 +422,37 @@ styles = jss
415422
}
416423

417424
, "&:hover lumi-select-input": lumiInputHoverStyles
418-
, "&:focus lumi-select-input, & lumi-select-inner[data-focus=\"true\"] lumi-select-input": lumiInputFocusStyles
425+
426+
, "&:focus lumi-select-input, & lumi-select-inner[data-focus=\"true\"] lumi-select-input":
427+
{ extend: lumiInputFocusStyles
428+
, "& lumi-select-input-placeholder":
429+
{ display: "none"
430+
}
431+
}
432+
419433
, "&[data-disabled=\"true\"] lumi-select-input": lumiInputDisabledStyles
420434

421435
, "& lumi-select-input-selected-values":
422436
{ margin: "-2px" -- (gap)
423437

424438
, display: "flex"
425439
, flexFlow: "row wrap"
426-
, flex: "1"
440+
, flex: "1 1 auto"
441+
, minWidth: 0
427442

428443
, "& > lumi-select-input-selected-value, & > lumi-select-input-placeholder, & > input.select-native-input":
429444
{ margin: "2px" -- (gap)
430445
}
431-
, "& > lumi-select-input-placeholder":
432-
{ position: "absolute"
433-
}
434446
}
435447

436448
, "& lumi-select-input-placeholder":
437449
{ color: cssStringHSLA colors.black2
438450
, lineHeight: "32px"
451+
, flex: "1 1 0%"
452+
, display: "block"
453+
, overflow: "hidden"
454+
, whiteSpace: "nowrap"
455+
, textOverflow: "ellipsis"
439456
, "@media (min-width: 860px)":
440457
{ lineHeight: "24px"
441458
}
@@ -444,22 +461,30 @@ styles = jss
444461

445462
, "& lumi-select-input-selected-value":
446463
{ display: "flex"
464+
, flex: "0 1 auto"
447465
, flexFlow: "row"
448466
, alignItems: "center"
449467
, padding: "0 7px"
468+
, minWidth: 0
450469
, lineHeight: "32px"
451470
, "@media (min-width: 860px)":
452471
{ lineHeight: "24px"
453472
}
473+
, "& > lumi-select-input-selected-value-text":
474+
{ display: "block"
475+
, lineHeight: "inherit"
476+
, overflow: "hidden"
477+
, whiteSpace: "nowrap"
478+
, textOverflow: "ellipsis"
479+
}
454480
, "& > lumi-select-clear-icon": { display: "none" }
455481
}
456482
, "& lumi-select-input-selected-value + input.select-native-input":
457483
{ visibility: "hidden"
458484
}
459485

460486
, "& input.select-native-input":
461-
{ flex: "1"
462-
, width: "100%"
487+
{ flex: "1 1 0%"
463488
, minWidth: "40px"
464489
, appearance: "none"
465490
, border: "none"
@@ -477,6 +502,7 @@ styles = jss
477502
, cursor: "pointer"
478503
, height: "26px"
479504
, width: "20px"
505+
, flex: "0 0 auto"
480506
, paddingTop: "3px"
481507
, "@media (min-width: 860px)":
482508
{ paddingTop: "0"
@@ -504,13 +530,15 @@ styles = jss
504530
, "& lumi-select-input-selected-value + input.select-native-input":
505531
{ visibility: "visible"
506532
, padding: "0 7px 0 1px"
533+
}
507534

508-
-- hide the blank input line when not in focus
509-
, "&[value=\"\"]:not(:focus)":
510-
{ flex: "unset"
511-
, width: "0"
512-
, minWidth: "0"
513-
}
535+
-- hide the blank input line when not in focus
536+
, "& input.select-native-input[value=\"\"]:not(:focus)":
537+
{ width: 0
538+
, minWidth: 0
539+
, padding: 0
540+
, margin: 0
541+
, flex: "0 1 0%"
514542
}
515543
}
516544

@@ -595,7 +623,7 @@ styles = jss
595623
, display: "flex"
596624
, flexFlow: "column"
597625
, justifyContent: "center"
598-
, padding: "0 9px"
626+
, padding: "6px 9px"
599627
, minHeight: "32px"
600628
, cursor: "initial"
601629
, overflow: "hidden"

0 commit comments

Comments
 (0)