git.iko.soy/typeable/elm-ui
on master help sign in
Add support for font variants. resolves #16
be7356bMatthew Griffith
src/Element/Font.elm+142
@@ -5,6 +5,7 @@ module Element.Font exposing
5 , alignLeft, alignRight, center, justify, letterSpacing, wordSpacing
5 , alignLeft, alignRight, center, justify, letterSpacing, wordSpacing
6 , underline, strike, italic, unitalicized
6 , underline, strike, italic, unitalicized
7 , heavy, extraBold, bold, semiBold, medium, regular, light, extraLight, hairline
7 , heavy, extraBold, bold, semiBold, medium, regular, light, extraLight, hairline
8+ , Variant, variant, smallCaps, slashedZero, ligatures, ordinal, tabularNumbers, stackedFractions, diagonalFractions, swash, disable, feature, indexed
8 , glow, shadow
9 , glow, shadow
9 )
10 )
10
11
@@ -70,6 +71,11 @@ module Element.Font exposing
70@docs heavy, extraBold, bold, semiBold, medium, regular, light, extraLight, hairline
71@docs heavy, extraBold, bold, semiBold, medium, regular, light, extraLight, hairline
71
72
72
73
74+## Variants
75+
76+@docs Variant, variant, smallCaps, slashedZero, ligatures, ordinal, tabularNumbers, stackedFractions, diagonalFractions, swash, disable, feature, indexed
77+
78+
73## Shadows
79## Shadows
74
80
75@docs glow, shadow
81@docs glow, shadow
@@ -151,6 +157,7 @@ with :
151 { name : String
157 { name : String
152 , adjustment : Adjustment
158 , adjustment : Adjustment
153 , url : Maybe String
159 , url : Maybe String
160+ , variants : List Variant
154 }
161 }
155 -> Font
162 -> Font
156with =
163with =
@@ -333,3 +340,138 @@ glow clr i =
333 in
340 in
334 Internal.StyleClass Flag.txtShadows <|
341 Internal.StyleClass Flag.txtShadows <|
335 Internal.Single (Internal.textShadowName shade) "text-shadow" (Internal.formatTextShadow shade)
342 Internal.Single (Internal.textShadowName shade) "text-shadow" (Internal.formatTextShadow shade)
343+
344+
345+
346+{- Variants -}
347+
348+
349+type alias Variant =
350+ Internal.Variant
351+
352+
353+{-| You can use this to set a single variant on an element itself such as:
354+
355+ el
356+ [ Font.variant Font.smallcaps
357+ ]
358+ (text "rendered with smallcaps")
359+
360+**Note** These will **not** stack. If you want multiple variants, you should use `Font.with`.
361+
362+-}
363+variant : Variant -> Attribute msg
364+variant var =
365+ case var of
366+ Internal.VariantActive name ->
367+ Internal.Class Flag.fontVariant ("v-" ++ name)
368+
369+ Internal.VariantOff name ->
370+ Internal.Class Flag.fontVariant ("v-" ++ name ++ "-off")
371+
372+ Internal.VariantIndexed name index ->
373+ Internal.StyleClass Flag.fontVariant <|
374+ Internal.Single ("v-" ++ name ++ "-" ++ String.fromInt index)
375+ "font-feature-settings"
376+ ("\"" ++ name ++ "\" " ++ String.fromInt index)
377+
378+
379+{-| Less often you might want to disable an active variant.
380+
381+ el
382+ [ Font.variant (Font.disable Font.smallCaps)
383+ ]
384+ (text "Is not smallcaps")
385+
386+**Note** Generally try to set yourself up so that this isn't really necessary.
387+
388+-}
389+disable : Variant -> Variant
390+disable var =
391+ case var of
392+ Internal.VariantActive name ->
393+ Internal.VariantOff name
394+
395+ Internal.VariantIndexed name index ->
396+ Internal.VariantOff name
397+
398+ Internal.VariantOff name ->
399+ var
400+
401+
402+{-| [Small caps](https://en.wikipedia.org/wiki/Small_caps) are rendered using uppercase glyphs, but at the size of lowercase glyphs.
403+-}
404+smallCaps : Variant
405+smallCaps =
406+ Internal.VariantActive "smcp"
407+
408+
409+{-| Add a slash when rendering `0`
410+-}
411+slashedZero : Variant
412+slashedZero =
413+ Internal.VariantActive "zero"
414+
415+
416+{-| -}
417+ligatures : Variant
418+ligatures =
419+ Internal.VariantActive "liga"
420+
421+
422+{-| Oridinal markers like `1st` and `2nd` will receive special glyphs.
423+-}
424+ordinal : Variant
425+ordinal =
426+ Internal.VariantActive "ordn"
427+
428+
429+{-| Number figures will each take up the same space, allowing them to be easily aligned, such as in tables.
430+-}
431+tabularNumbers : Variant
432+tabularNumbers =
433+ Internal.VariantActive "tnum"
434+
435+
436+{-| Render fractions with the numerator stacked on top of the denominator.
437+-}
438+stackedFractions : Variant
439+stackedFractions =
440+ Internal.VariantActive "afrc"
441+
442+
443+{-| Render fractions
444+-}
445+diagonalFractions : Variant
446+diagonalFractions =
447+ Internal.VariantActive "frac"
448+
449+
450+{-| -}
451+swash : Int -> Variant
452+swash =
453+ Internal.VariantIndexed "swsh"
454+
455+
456+{-| Set a feature by name and whether it should be on or off.
457+
458+Feature names are four-letter names as defined in the [OpenType specification](https://docs.microsoft.com/en-us/typography/opentype/spec/featurelist).
459+
460+-}
461+feature : String -> Bool -> Variant
462+feature name on =
463+ if on then
464+ Internal.VariantIndexed name 1
465+
466+ else
467+ Internal.VariantIndexed name 0
468+
469+
470+{-| A font variant might have multiple versions within the font.
471+
472+In these cases we need to specify the index of the version we want.
473+
474+-}
475+indexed : String -> Int -> Variant
476+indexed name on =
477+ Internal.VariantIndexed name on
src/Internal/Flag.elm+5
@@ -22,6 +22,7 @@ module Internal.Flag exposing
22 , fontColor
22 , fontColor
23 , fontFamily
23 , fontFamily
24 , fontSize
24 , fontSize
25+ , fontVariant
25 , fontWeight
26 , fontWeight
26 , gridPosition
27 , gridPosition
27 , gridTemplate
28 , gridTemplate
@@ -318,3 +319,7 @@ behind =
318
319
319heightTextAreaContent =
320heightTextAreaContent =
320 flag 47
321 flag 47
322+
323+
324+fontVariant =
325+ flag 48
src/Internal/Model.elm+38−3
@@ -29,6 +29,7 @@ module Internal.Model exposing
29 , TransformComponent(..)
29 , TransformComponent(..)
30 , Transformation(..)
30 , Transformation(..)
31 , VAlign(..)
31 , VAlign(..)
32+ , Variant(..)
32 , XYZ
33 , XYZ
33 , addNodeName
34 , addNodeName
34 , addWhen
35 , addWhen
@@ -223,9 +224,37 @@ type Font
223 { name : String
224 { name : String
224 , url : Maybe String
225 , url : Maybe String
225 , adjustment : Adjustment
226 , adjustment : Adjustment
227+ , variants : List Variant
226 }
228 }
227
229
228
230
231+type Variant
232+ = VariantActive String
233+ | VariantOff String
234+ | VariantIndexed String Int
235+
236+
237+renderVariant var =
238+ case var of
239+ VariantActive name ->
240+ "\"" ++ name ++ "\""
241+
242+ VariantOff name ->
243+ "\"" ++ name ++ "\" 0"
244+
245+ VariantIndexed name index ->
246+ "\"" ++ name ++ "\" " ++ String.fromInt index
247+
248+
249+renderVariants typeface =
250+ case typeface of
251+ FontWith font ->
252+ String.join ", " (List.map renderVariant font.variants)
253+
254+ _ ->
255+ ""
256+
257+
229type Property
258type Property
230 = Property String String
259 = Property String String
231
260
@@ -2474,18 +2503,25 @@ toStyleSheetString options stylesheet =
2474
2503
2475 FontFamily name typefaces ->
2504 FontFamily name typefaces ->
2476 let
2505 let
2506+ features =
2507+ typefaces
2508+ |> List.map renderVariants
2509+ |> String.join ", "
2510+
2477 families =
2511 families =
2478− Property "font-family"
2512+ [ Property "font-family"
2479 (typefaces
2513 (typefaces
2480 |> List.map fontName
2514 |> List.map fontName
2481 |> String.join ", "
2515 |> String.join ", "
2482 )
2516 )
2517+ , Property "font-feature-settings" features
2518+ ]
2483 in
2519 in
2484 String.join " "
2520 String.join " "
2485 [ renderStyle
2521 [ renderStyle
2486 maybePseudo
2522 maybePseudo
2487 ("." ++ name)
2523 ("." ++ name)
2488− [ families ]
2524+ families
2489 ]
2525 ]
2490
2526
2491 Single class prop val ->
2527 Single class prop val ->
@@ -3285,7 +3321,6 @@ convertAdjustment adjustment =
3285 capitalVertical =
3321 capitalVertical =
3286 1 - ascender
3322 1 - ascender
3287
3323
3288−
3289 capitalSize =
3324 capitalSize =
3290 1 / (ascender - newBaseline)
3325 1 / (ascender - newBaseline)
3291
3326
src/Internal/Style.elm+29
@@ -785,7 +785,36 @@ commonValues =
785 Class (".p-" ++ String.fromInt i) [ Prop "padding" (String.fromInt i ++ "px") ]
785 Class (".p-" ++ String.fromInt i) [ Prop "padding" (String.fromInt i ++ "px") ]
786 )
786 )
787 (List.range 0 24)
787 (List.range 0 24)
788+
789+ -- Common Font Variants
790+ , [ Class ".v-smcp"
791+ [ Prop "font-variant" "small-caps"
792+ ]
793+ , Class ".v-smcp-off"
794+ [ Prop "font-variant" "normal"
795+ ]
796+ ]
797+
798+ -- , fontVariant "smcp"
799+ , fontVariant "zero"
800+ , fontVariant "onum"
801+ , fontVariant "liga"
802+ , fontVariant "dlig"
803+ , fontVariant "ordn"
804+ , fontVariant "tnum"
805+ , fontVariant "afrc"
806+ , fontVariant "frac"
807+ ]
808+
809+
810+fontVariant var =
811+ [ Class (".v-" ++ var)
812+ [ Prop "font-feature-settings" ("\"" ++ var ++ "\"")
788 ]
813 ]
814+ , Class (".v-" ++ var ++ "-off")
815+ [ Prop "font-feature-settings" ("\"" ++ var ++ "\" 0")
816+ ]
817+ ]
789
818
790
819
791rules : String
820rules : String
tests/suite/Flags.elm+4−1
@@ -1,4 +1,4 @@
1−module Main exposing (..)
1+module Main exposing (allFlags, doesntInvalidateOthers, invalidateSelf, main)
2
2
3import Html
3import Html
4import Internal.Flag as Flag
4import Internal.Flag as Flag
@@ -18,6 +18,7 @@ main =
18invalidateSelf i flag =
18invalidateSelf i flag =
19 if Flag.present flag (Flag.add flag Flag.none) then
19 if Flag.present flag (Flag.add flag Flag.none) then
20 Html.text ""
20 Html.text ""
21+
21 else
22 else
22 Html.div [] [ Html.text (toString (Flag.value flag) ++ " at index " ++ toString i ++ " does not invalidate itself") ]
23 Html.div [] [ Html.text (toString (Flag.value flag) ++ " at index " ++ toString i ++ " does not invalidate itself") ]
23
24
@@ -38,6 +39,7 @@ doesntInvalidateOthers i flag =
38 in
39 in
39 if passing then
40 if passing then
40 Html.text ""
41 Html.text ""
42+
41 else
43 else
42 Html.div []
44 Html.div []
43 [ Html.text (toString (Flag.value flag) ++ " at index " ++ toString i ++ " invalidates other flags!")
45 [ Html.text (toString (Flag.value flag) ++ " at index " ++ toString i ++ " invalidates other flags!")
@@ -86,4 +88,5 @@ allFlags =
86 , Flag.alignBottom
88 , Flag.alignBottom
87 , Flag.centerX
89 , Flag.centerX
88 , Flag.centerY
90 , Flag.centerY
91+ , Flag.fontVariant
89 ]
92 ]