From 803fb12b643ac13c29126e9c911098aa7630939d Mon Sep 17 00:00:00 2001 From: Finn Olav Sagen Date: Sun, 5 Apr 2026 11:59:34 +0200 Subject: [PATCH 1/9] FS.FluentUI to Felizv3 --- .../.config/dotnet-tools.json | 18 ------- src/FS.FluentUI/FS.FluentUI.fsproj | 3 +- src/FS.FluentUI/FelizProps.fs | 2 +- src/FS.FluentUI/FluentUI.fs | 48 +++++++++---------- src/FS.FluentUI/Props.fs | 12 ++--- src/FS.FluentUI/Props2.fs | 22 ++++----- src/FS.FluentUI/Utils.fs | 4 ++ 7 files changed, 48 insertions(+), 61 deletions(-) delete mode 100644 src/FS.FluentUI.TestGrounds/.config/dotnet-tools.json diff --git a/src/FS.FluentUI.TestGrounds/.config/dotnet-tools.json b/src/FS.FluentUI.TestGrounds/.config/dotnet-tools.json deleted file mode 100644 index 28af286..0000000 --- a/src/FS.FluentUI.TestGrounds/.config/dotnet-tools.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "version": 1, - "isRoot": true, - "tools": { - "fable": { - "version": "4.1.4", - "commands": [ - "fable" - ] - }, - "fantomas": { - "version": "6.1.3", - "commands": [ - "fantomas" - ] - } - } -} \ No newline at end of file diff --git a/src/FS.FluentUI/FS.FluentUI.fsproj b/src/FS.FluentUI/FS.FluentUI.fsproj index 1af456b..33ea4c7 100644 --- a/src/FS.FluentUI/FS.FluentUI.fsproj +++ b/src/FS.FluentUI/FS.FluentUI.fsproj @@ -34,10 +34,11 @@ + - + diff --git a/src/FS.FluentUI/FelizProps.fs b/src/FS.FluentUI/FelizProps.fs index 7766775..6d3b89e 100644 --- a/src/FS.FluentUI/FelizProps.fs +++ b/src/FS.FluentUI/FelizProps.fs @@ -337,7 +337,7 @@ type prop<'Property> = /// Children of this React element. static member inline children (value: Fable.React.ReactElement) = Interop.mkProperty<'Property> "children" value /// Children of this React element. - static member inline children (elems: Fable.React.ReactElement seq) = Interop.mkProperty<'Property> "children" (Interop.reactApi.Children.toArray (Array.ofSeq elems)) + static member inline children (elems: Fable.React.ReactElement seq) = Interop.mkProperty<'Property> "children" (Array.ofSeq elems) /// A URL that designates a source document or message for the information quoted. This attribute is intended to /// point to information explaining the context or the reference for the quote. diff --git a/src/FS.FluentUI/FluentUI.fs b/src/FS.FluentUI/FluentUI.fs index af3c6bb..5ee7f24 100644 --- a/src/FS.FluentUI/FluentUI.fs +++ b/src/FS.FluentUI/FluentUI.fs @@ -14,11 +14,11 @@ module FelizOverloads = /// *This is a custom overload that accepts a `Theme.tokens` string variable.*
/// SVG attribute to define the size of the font from baseline to baseline when multiple /// lines of text are set solid in a multiline layout environment. - static member inline fontSize (value: string) = Interop.mkAttr "fontSize" value + static member inline fontSize (value: string) = PropHelper.mkAttr "fontSize" value /// *This is a custom overload that accepts a `Theme.tokens` string variable.*
/// SVG attribute to define the width of the stroke to be applied to the shape. /// This is an overload that accepts Theme.tokens string variables in FS.FluentUI - static member inline strokeWidth (value: string) = Interop.mkAttr "strokeWidth" value + static member inline strokeWidth (value: string) = PropHelper.mkAttr "strokeWidth" value type style with /// *This is a custom overload that accepts a `Theme.tokens` string variable.*
@@ -29,27 +29,27 @@ module FelizOverloads = /// **Tip**: A positioned element is an element with the position property set to: relative, absolute, or fixed. /// /// **Tip**: This property is useful if you want to create overlapping elements. - static member inline zIndex (value: string) = Interop.mkStyle "zIndex" value + static member inline zIndex (value: string) = StyleHelper.mkStyle "zIndex" value /// *This is a custom overload that accepts a `Theme.tokens` string variable.*
/// Sets the length of time a transition animation should take to complete. By default, the /// value is 0s, meaning that no animation will occur. - static member inline transitionDuration (timespan: string) = Interop.mkStyle "transitionDuration" timespan + static member inline transitionDuration (timespan: string) = StyleHelper.mkStyle "transitionDuration" timespan /// *This is a custom overload that accepts a `Theme.tokens` string variable.*
/// Sets the length of time a transition animation should take to complete. By default, the /// value is 0s, meaning that no animation will occur. - static member inline transitionDurationMilliseconds (value: string) = Interop.mkStyle "transitionDuration" value + static member inline transitionDurationMilliseconds (value: string) = StyleHelper.mkStyle "transitionDuration" value /// *This is a custom overload that accepts a `Theme.tokens` string variable.*
/// Specifies the duration to wait before starting a property's transition effect when its value changes. - static member inline transitionDelay (timespan: string) = Interop.mkStyle "transitionDelay" timespan + static member inline transitionDelay (timespan: string) = StyleHelper.mkStyle "transitionDelay" timespan /// *This is a custom overload that accepts a `Theme.tokens` string variable.*
/// Specifies the duration to wait before starting a property's transition effect when its value changes. - static member inline transitionDelayMilliseconds (value: string) = Interop.mkStyle "transitionDelay" value + static member inline transitionDelayMilliseconds (value: string) = StyleHelper.mkStyle "transitionDelay" value /// *This is a custom overload that accepts a `Theme.tokens` string variable.*
/// The transition property is a shorthand property for transition-property, transition-duration, /// transition-timing-function, transition-delay, and transition-behavior. /// https://developer.mozilla.org/en-US/docs/Web/CSS/transition static member inline transition (property: Styles.ITransitionProperty, duration: string) = - Interop.mkStyle "transition" ( + StyleHelper.mkStyle "transition" ( unbox property + " " + duration ) @@ -57,7 +57,7 @@ module FelizOverloads = /// transition-timing-function, transition-delay, and transition-behavior. /// https://developer.mozilla.org/en-US/docs/Web/CSS/transition static member inline transition (property: string, duration: string) = - Interop.mkStyle "transition" ( + StyleHelper.mkStyle "transition" ( property + " " + duration ) @@ -66,7 +66,7 @@ module FelizOverloads = /// transition-timing-function, transition-delay, and transition-behavior. /// https://developer.mozilla.org/en-US/docs/Web/CSS/transition static member inline transition (property: Styles.ITransitionProperty, duration: string, timingFunction: Styles.ITransitionTimingFunction) = - Interop.mkStyle "transition" ( + StyleHelper.mkStyle "transition" ( unbox property + " " + duration + " " + unbox timingFunction @@ -76,7 +76,7 @@ module FelizOverloads = /// transition-timing-function, transition-delay, and transition-behavior. /// https://developer.mozilla.org/en-US/docs/Web/CSS/transition static member inline transition (property: string, duration: string, timingFunction: Styles.ITransitionTimingFunction) = - Interop.mkStyle "transition" ( + StyleHelper.mkStyle "transition" ( property + " " + duration + " " + unbox timingFunction @@ -86,7 +86,7 @@ module FelizOverloads = /// transition-timing-function, transition-delay, and transition-behavior. /// https://developer.mozilla.org/en-US/docs/Web/CSS/transition static member inline transition (property: Styles.ITransitionProperty, durationInMs: string, delayInMs: string) = - Interop.mkStyle "transition" ( + StyleHelper.mkStyle "transition" ( unbox property + " " + durationInMs + " " + delayInMs @@ -96,7 +96,7 @@ module FelizOverloads = /// transition-timing-function, transition-delay, and transition-behavior. /// https://developer.mozilla.org/en-US/docs/Web/CSS/transition static member inline transition (property: string, durationInMs: string, delayInMs: string) = - Interop.mkStyle "transition" ( + StyleHelper.mkStyle "transition" ( property + " " + durationInMs + " " + delayInMs @@ -106,7 +106,7 @@ module FelizOverloads = /// transition-timing-function, transition-delay, and transition-behavior. /// https://developer.mozilla.org/en-US/docs/Web/CSS/transition static member inline transition (property: Styles.ITransitionProperty, durationInMs: string, timingFunction: Styles.ITransitionTimingFunction, delayInMs: string) = - Interop.mkStyle "transition" ( + StyleHelper.mkStyle "transition" ( unbox property + " " + durationInMs + " " + unbox timingFunction, @@ -117,7 +117,7 @@ module FelizOverloads = /// transition-timing-function, transition-delay, and transition-behavior. /// https://developer.mozilla.org/en-US/docs/Web/CSS/transition static member inline transition (property: string, durationInMs: string, timingFunction: Styles.ITransitionTimingFunction, delayInMs: string) = - Interop.mkStyle "transition" ( + StyleHelper.mkStyle "transition" ( property + " " + durationInMs + " " + unbox timingFunction, @@ -127,7 +127,7 @@ module FelizOverloads = /// Sets the size of the font. /// /// This property is also used to compute the size of em, ex, and other relative units. - static member inline fontSize (size: string) = Interop.mkStyle "fontSize" size + static member inline fontSize (size: string) = StyleHelper.mkStyle "fontSize" size /// *This is a custom overload that accepts a `Theme.tokens` string variable.*
/// Sets the height of a line box. It's commonly used to set the distance between lines of text. /// On block-level elements, it specifies the minimum height of line boxes within the element. @@ -137,30 +137,30 @@ module FelizOverloads = /// This property is also used to compute the size of em, ex, and other relative units. /// /// Note: Negative values are not allowed. - static member inline lineHeight (size: string) = Interop.mkStyle "lineHeight" size + static member inline lineHeight (size: string) = StyleHelper.mkStyle "lineHeight" size /// *This is a custom overload that accepts a `Theme.tokens` string variable.*
/// Rounds the corners of an element's outer border edge. You can set a single radius to make /// circular corners, or two radii to make elliptical corners. - static member inline borderRadius (radius: string) = Interop.mkStyle "borderRadius" radius + static member inline borderRadius (radius: string) = StyleHelper.mkStyle "borderRadius" radius /// *This is a custom overload that accepts a `Theme.tokens` string variable.*
/// Sets the length of time that an animation takes to complete one cycle. - static member inline animationDuration (timespan: string) = Interop.mkStyle "animationDuration" timespan + static member inline animationDuration (timespan: string) = StyleHelper.mkStyle "animationDuration" timespan /// *This is a custom overload that accepts a `Theme.tokens` string variable.*
/// Sets when an animation starts. /// /// The animation can start later, immediately from its beginning, or immediately and partway through the animation. - static member inline animationDelay (timespan: string) = Interop.mkStyle "animationDelay" timespan + static member inline animationDelay (timespan: string) = StyleHelper.mkStyle "animationDelay" timespan /// *This is a custom overload that accepts a `Theme.tokens` string variable.*
/// Defines from thin to thick characters. 400 is the same as normal, and 700 is the same as bold. - static member inline fontWeight (weight: string) = Interop.mkStyle "fontWeight" weight + static member inline fontWeight (weight: string) = StyleHelper.mkStyle "fontWeight" weight /// *This is a custom overload that accepts a `Theme.tokens` string variable.*
/// Adds shadow effects around an element's frame. /// /// A box shadow is described by X and Y offsets relative to the element, blur and spread radii, and color. - static member inline boxShadow (value: string) = Interop.mkStyle "boxShadow" value + static member inline boxShadow (value: string) = StyleHelper.mkStyle "boxShadow" value /// *This is a custom overload that accepts a `Theme.tokens` string variable.*
/// Specifies extra inter-character space in addition to the default space between characters. - static member inline letterSpacing (value: string) = Interop.mkStyle "letterSpacing" value + static member inline letterSpacing (value: string) = StyleHelper.mkStyle "letterSpacing" value module internal Shorthand = @@ -1001,7 +1001,7 @@ type [] Fui = // TeachingPopover static member inline teachingPopover (props: ITeachingPopoverProp list) = createElement (import "TeachingPopover" FluentUIv9) props static member inline teachingPopover (props: ReactElement list) = Interop.reactElementWithChildren (import "TeachingPopover" FluentUIv9) props - static member inline teachingPopoverTrigger (props: ReactElement) = createElement (import "TeachingPopoverTrigger" FluentUIv9) [prop.children (props)] + static member inline teachingPopoverTrigger (props: ReactElement) = Interop.reactElementWithChildren (import "TeachingPopoverTrigger" FluentUIv9) [props] static member inline teachingPopoverTrigger (props: ITeachingPopoverTriggerProp list) = createElement (import "TeachingPopoverTrigger" FluentUIv9) props static member inline teachingPopoverSurface (props: ITeachingPopoverSurfaceProp list) = createElement (import "TeachingPopoverSurface" FluentUIv9) props static member inline teachingPopoverSurface (props: ReactElement list) = Interop.reactElementWithChildren (import "TeachingPopoverSurface" FluentUIv9) props diff --git a/src/FS.FluentUI/Props.fs b/src/FS.FluentUI/Props.fs index fe1f408..e6d450a 100644 --- a/src/FS.FluentUI/Props.fs +++ b/src/FS.FluentUI/Props.fs @@ -380,7 +380,7 @@ type [] checkbox = /// WARNING: Checkbox doesn't support children. Using this prop will cause runtime errors. [] static member inline children (value: ReactElement) = Interop.mkProperty "children" value /// WARNING: Checkbox doesn't support children. Using this prop will cause runtime errors. - [] static member inline children ([] elems: ReactElement seq) = Interop.mkProperty "children" (Interop.reactApi.Children.toArray elems) + [] static member inline children ([] elems: ReactElement seq) = Interop.mkProperty "children" (Array.ofSeq elems) /// The root element of the Checkbox. /// The root slot receives the className and style specified directly on the . All other native props will be applied to the primary slot: input static member inline root (value: IReactProperty list) = Interop.mkProperty "root" (!!value |> createObj |> unbox) @@ -985,7 +985,7 @@ type [] menu = match elems |> Seq.length with | l when l <= 2 -> elems | _ -> elems |> Seq.take 2 - Interop.mkProperty "children" (Interop.reactApi.Children.toArray elemsToUse) + Interop.mkProperty "children" (Array.ofSeq elemsToUse) /// Sets the delay for mouse open/close for the popover one mouse enter/leave static member inline hoverDelay (value: int) = Interop.mkProperty "hoverDelay" value /// Root menus are rendered out of DOM order on document.body, use this to render the menu in DOM order This option is disregarded for submenus @@ -1299,7 +1299,7 @@ type [] popover = match elems |> Seq.length with | l when l <= 2 -> elems | _ -> elems |> Seq.take 2 - Interop.mkProperty "children" (Interop.reactApi.Children.toArray elemsToUse) + Interop.mkProperty "children" (Array.ofSeq elemsToUse) /// Close when scroll outside of it static member inline closeOnScroll (value: bool) = Interop.mkProperty "closeOnScroll" value /// Used to set the initial open state of the Popover in uncontrolled mode @@ -1500,7 +1500,7 @@ type [] input = /// WARNING: Input doesn't support children. Using this prop will cause runtime errors. [] static member inline children (value: ReactElement) = Interop.mkProperty "children" value /// WARNING: Input doesn't support children. Using this prop will cause runtime errors. - [] static member inline children ([] elems: ReactElement seq) = Interop.mkProperty "children" (Interop.reactApi.Children.toArray elems) + [] static member inline children ([] elems: ReactElement seq) = Interop.mkProperty "children" (Array.ofSeq elems) /// Wrapper element which visually appears to be the input and is used for borders, focus styling, etc. /// (A wrapper is needed to properly position contentBefore and contentAfter relative to input.) /// The root slot receives the className and style specified directly on the . All other top-level native props will be applied to the primary slot, input. @@ -2905,7 +2905,7 @@ type [] dialog = match elems |> Seq.length with | l when l <= 2 -> elems | _ -> elems |> Seq.take 2 - Interop.mkProperty "children" (Interop.reactApi.Children.toArray elemsToUse) + Interop.mkProperty "children" (Array.ofSeq elemsToUse) /// Callback fired when the component changes value from open state. static member inline onOpenChange (handler: DialogOpenChangeData -> unit) = Interop.mkProperty "onOpenChange" (System.Func<_,_,_> (fun _ value -> handler value)) /// Callback fired when the component changes value from open state. @@ -3330,7 +3330,7 @@ type [] datePicker = /// WARNING: DatePicker doesn't support children. Using this prop will cause runtime errors. [] static member inline children (value: ReactElement) = Interop.mkProperty "children" value /// WARNING: DatePicker doesn't support children. Using this prop will cause runtime errors. - [] static member inline children ([] elems: ReactElement seq) = Interop.mkProperty "children" (Interop.reactApi.Children.toArray elems) + [] static member inline children ([] elems: ReactElement seq) = Interop.mkProperty "children" (Array.ofSeq elems) /// Called when the user changes the input's value. static member inline onChange (handler: ValueProp -> unit) = Interop.mkProperty "onChange" (System.Func<_,_,_> (fun _ value -> handler value)) /// Called when the user changes the input's value. diff --git a/src/FS.FluentUI/Props2.fs b/src/FS.FluentUI/Props2.fs index 35270f2..d3d3abc 100644 --- a/src/FS.FluentUI/Props2.fs +++ b/src/FS.FluentUI/Props2.fs @@ -514,7 +514,7 @@ type [] virtualizer = /// WARNING: Virtualizer only takes a render function as children. Using this will cause runtime errors. [] static member inline children (value: Fable.React.ReactElement) = Interop.mkProperty "children" value /// WARNING: Virtualizer only takes a render function as children. Using this will cause runtime errors. - [] static member inline children ([] elems: Fable.React.ReactElement seq) = Interop.mkProperty "children" (Interop.reactApi.Children.toArray elems) + [] static member inline children ([] elems: Fable.React.ReactElement seq) = Interop.mkProperty "children" (Array.ofSeq elems) /// Child render function. /// Iteratively called to return current virtualizer DOM children. /// Will act as a row or column indexer depending on Virtualizer settings. @@ -661,7 +661,7 @@ type [] virtualizerScrollView = /// WARNING: VirtualizerScrollView only takes a render function as children. Using this will cause runtime errors. [] static member inline children (value: Fable.React.ReactElement) = Interop.mkProperty "children" value /// WARNING: VirtualizerScrollView only takes a render function as children. Using this will cause runtime errors. - [] static member inline children ([] elems: Fable.React.ReactElement seq) = Interop.mkProperty "children" (Interop.reactApi.Children.toArray elems) + [] static member inline children ([] elems: Fable.React.ReactElement seq) = Interop.mkProperty "children" (Array.ofSeq elems) /// Child render function. /// Iteratively called to return current virtualizer DOM children. /// Will act as a row or column indexer depending on Virtualizer settings. @@ -791,7 +791,7 @@ type [] virtualizerScrollViewDynamic = /// WARNING: VirtualizerScrollViewDynamic only takes a render function as children. Using this will cause runtime errors. [] static member inline children (value: Fable.React.ReactElement) = Interop.mkProperty "children" value /// WARNING: VirtualizerScrollViewDynamic only takes a render function as children. Using this will cause runtime errors. - [] static member inline children ([] elems: Fable.React.ReactElement seq) = Interop.mkProperty "children" (Interop.reactApi.Children.toArray elems) + [] static member inline children ([] elems: Fable.React.ReactElement seq) = Interop.mkProperty "children" (Array.ofSeq elems) /// Child render function. /// Iteratively called to return current virtualizer DOM children. /// Will act as a row or column indexer depending on Virtualizer settings. @@ -1922,7 +1922,7 @@ type [] searchBox = /// WARNING: Searchbox doesn't support children. Using this prop will cause runtime errors. [] static member inline children (value: ReactElement) = Interop.mkProperty "children" value /// WARNING: Searchbox doesn't support children. Using this prop will cause runtime errors. - [] static member inline children ([] elems: ReactElement seq) = Interop.mkProperty "children" (Interop.reactApi.Children.toArray elems) + [] static member inline children ([] elems: ReactElement seq) = Interop.mkProperty "children" (Array.ofSeq elems) static member inline root (value: IReactProperty list) = Interop.mkProperty "root" (!!value |> createObj |> unbox) /// Hidden input that handles the checkbox's functionality. /// This is the PRIMARY slot: all native properties specified directly on will be applied to this slot, except className and style, which remain on the root slot. @@ -2521,7 +2521,7 @@ type [] teachingPopover = match elems |> Seq.length with | l when l <= 2 -> elems | _ -> elems |> Seq.take 2 - Interop.mkProperty "children" (Interop.reactApi.Children.toArray elemsToUse) + Interop.mkProperty "children" (Array.ofSeq elemsToUse) /// Close when scroll outside of it static member inline closeOnScroll (value: bool) = Interop.mkProperty "closeOnScroll" value /// Used to set the initial open state of the Popover in uncontrolled mode @@ -2738,7 +2738,7 @@ type [] teachingPopoverCarouselNav = /// WARNING: TeachingPopoverCarouselNav only takes a render function as children. Using this will cause runtime errors. [] static member inline children (value: Fable.React.ReactElement) = Interop.mkProperty "children" value /// WARNING: TeachingPopoverCarouselNav only takes a render function as children. Using this will cause runtime errors. - [] static member inline children ([] elems: Fable.React.ReactElement seq) = Interop.mkProperty "children" (Interop.reactApi.Children.toArray elems) + [] static member inline children ([] elems: Fable.React.ReactElement seq) = Interop.mkProperty "children" (Array.ofSeq elems) /// WARNING: TeachingPopoverCarouselNav only takes a render function as children. Using this will cause runtime errors. static member inline children (value: string -> ReactElement) = Interop.mkProperty "children" (System.Func<_,_> value) @@ -2992,7 +2992,7 @@ type [] tagPicker = match elems |> Seq.length with | l when l <= 2 -> elems | _ -> elems |> Seq.take 2 - Interop.mkProperty "children" (Interop.reactApi.Children.toArray elemsToUse) + Interop.mkProperty "children" (Array.ofSeq elemsToUse) module tagPicker = type [] size = @@ -3044,7 +3044,7 @@ type [] tagPickerInput = /// WARNING: TagPickerInput doesn't support children. Using this prop will cause runtime errors. [] static member inline children (value: ReactElement) = Interop.mkProperty "children" value /// WARNING: TagPickerInput doesn't support children. Using this prop will cause runtime errors. - [] static member inline children ([] elems: ReactElement seq) = Interop.mkProperty "children" (Interop.reactApi.Children.toArray elems) + [] static member inline children ([] elems: ReactElement seq) = Interop.mkProperty "children" (Array.ofSeq elems) module tagPickerInput = @@ -3078,7 +3078,7 @@ type [] tagPickerOption = match elems |> Seq.length with | l when l = 1 -> elems | _ -> elems |> Seq.take 1 - Interop.mkProperty "children" (Interop.reactApi.Children.toArray elemsToUse) + Interop.mkProperty "children" (Array.ofSeq elemsToUse) // -------------------------------------------------------------------------- TagPickerOptionGroup -------------------------------------------------------------------------------------- type [] tagPickerOptionGroup = @@ -3457,7 +3457,7 @@ type [] carouselNav = /// CarouselNav's children only takes an int -> ReactElement function [] static member inline children (value: Fable.React.ReactElement) = Interop.mkProperty<'Property> "children" value /// CarouselNav's children only takes an int -> ReactElement function - [] static member inline children (elems: Fable.React.ReactElement seq) = Interop.mkProperty<'Property> "children" (Interop.reactApi.Children.toArray (Array.ofSeq elems)) + [] static member inline children (elems: Fable.React.ReactElement seq) = Interop.mkProperty<'Property> "children" (Array.ofSeq elems) /// The total number of slides available. Users may override if using the component without a Carousel wrapper or implementing custom functionality. static member inline totalSlides (value: int) = Interop.mkProperty "totalSlides" value /// The total number of slides available. Users may override if using the component without a Carousel wrapper or implementing custom functionality. @@ -3871,7 +3871,7 @@ type [] virtualizedList = /// Optional CSS properties. The list of rows will fill the height defined by this style. static member inline style (value: obj)= Interop.mkProperty "style" value /// Additional content to be rendered within the list (above cells). This property can be used to render things like overlays or tooltips. - static member inline children ([] elems: Fable.React.ReactElement seq) = Interop.mkProperty "children" (Interop.reactApi.Children.toArray elems) + static member inline children ([] elems: Fable.React.ReactElement seq) = Interop.mkProperty "children" (Array.ofSeq elems) /// Default height of list for initial render. This value is important for server rendering. static member inline defaultHeight (value: int) = Interop.mkProperty "defaultHeight" value /// Ref used to interact with this component's imperative API. This API has imperative methods for scrolling and a getter for the outermost DOM element. diff --git a/src/FS.FluentUI/Utils.fs b/src/FS.FluentUI/Utils.fs index 30a4a0c..58e64e8 100644 --- a/src/FS.FluentUI/Utils.fs +++ b/src/FS.FluentUI/Utils.fs @@ -1,6 +1,8 @@ namespace FS.FluentUI open Fable.Core +open Fable.Core.JsInterop +open Fable.React type [] IFluentProviderProp = interface end type [] IAvatarProp = interface end @@ -276,3 +278,5 @@ type [] BundleIcons = { Filled: BundleIcon; Regular: Bun [] type Interop = static member inline mkProperty<'ControlProperty> (key:string) (value:obj) : 'ControlProperty = unbox (key, value) + static member inline reactElementWithChildren (el: ReactElementType) (children: #seq) : ReactElement = + ReactBindings.React.createElement (el, createObj [], children) From e95d1b70a95618c426d545c6512fbf8000e02e4a Mon Sep 17 00:00:00 2001 From: Finn Olav Sagen Date: Sun, 5 Apr 2026 12:00:02 +0200 Subject: [PATCH 2/9] FS.FluentUI.V8toV9 to Felizv3 --- src/FS.FluentUI.V8toV9/FS.FluentUI.V8toV9.fsproj | 3 ++- src/FS.FluentUI.V8toV9/FelizProps.fs | 2 +- src/FS.FluentUI.V8toV9/Utils.fs | 4 ++++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/FS.FluentUI.V8toV9/FS.FluentUI.V8toV9.fsproj b/src/FS.FluentUI.V8toV9/FS.FluentUI.V8toV9.fsproj index 9b688a0..8d6b46c 100644 --- a/src/FS.FluentUI.V8toV9/FS.FluentUI.V8toV9.fsproj +++ b/src/FS.FluentUI.V8toV9/FS.FluentUI.V8toV9.fsproj @@ -31,10 +31,11 @@ + - + diff --git a/src/FS.FluentUI.V8toV9/FelizProps.fs b/src/FS.FluentUI.V8toV9/FelizProps.fs index 9fb43a1..3428ad5 100644 --- a/src/FS.FluentUI.V8toV9/FelizProps.fs +++ b/src/FS.FluentUI.V8toV9/FelizProps.fs @@ -337,7 +337,7 @@ type prop<'Property> = /// Children of this React element. static member inline children (value: Fable.React.ReactElement) = Interop.mkProperty<'Property> "children" value /// Children of this React element. - static member inline children (elems: Fable.React.ReactElement seq) = Interop.mkProperty<'Property> "children" (Interop.reactApi.Children.toArray (Array.ofSeq elems)) + static member inline children (elems: Fable.React.ReactElement seq) = Interop.mkProperty<'Property> "children" (Array.ofSeq elems) /// A URL that designates a source document or message for the information quoted. This attribute is intended to /// point to information explaining the context or the reference for the quote. diff --git a/src/FS.FluentUI.V8toV9/Utils.fs b/src/FS.FluentUI.V8toV9/Utils.fs index e9421b7..ff6a01e 100644 --- a/src/FS.FluentUI.V8toV9/Utils.fs +++ b/src/FS.FluentUI.V8toV9/Utils.fs @@ -1,6 +1,8 @@ namespace FS.FluentUI.V8toV9 open Fable.Core +open Fable.Core.JsInterop +open Fable.React type [] IStackProp = interface end type [] IStackItemProp = interface end @@ -11,3 +13,5 @@ type [] IStackTokens = interface end [] type Interop = static member inline mkProperty<'ControlProperty> (key:string) (value:obj) : 'ControlProperty = unbox (key, value) + static member inline reactElementWithChildren (el: ReactElementType) (children: #seq) : ReactElement = + ReactBindings.React.createElement(el, createObj [], children) From e073db545320b880d4f7ac569628e449061161d6 Mon Sep 17 00:00:00 2001 From: Finn Olav Sagen Date: Sun, 5 Apr 2026 12:00:56 +0200 Subject: [PATCH 3/9] Bump charts to fable 4.5 --- src/FS.FluentUI.Charts/FS.FluentUI.Charts.fsproj | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/FS.FluentUI.Charts/FS.FluentUI.Charts.fsproj b/src/FS.FluentUI.Charts/FS.FluentUI.Charts.fsproj index 4dba2b2..e3a7b4d 100644 --- a/src/FS.FluentUI.Charts/FS.FluentUI.Charts.fsproj +++ b/src/FS.FluentUI.Charts/FS.FluentUI.Charts.fsproj @@ -31,10 +31,11 @@ + - + From 6ff0d2a0bf1f1d4b39860119dbd53d70a8606082 Mon Sep 17 00:00:00 2001 From: Finn Olav Sagen Date: Sun, 5 Apr 2026 12:01:28 +0200 Subject: [PATCH 4/9] TestGrounds to felizV3 --- src/FS.FluentUI.TestGrounds/src/TestGrounds.fs | 2 +- src/FS.FluentUI.TestGrounds/src/TestGrounds.fsproj | 7 +++++-- src/FS.FluentUI.TestGrounds/src/index.html | 4 ++-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/FS.FluentUI.TestGrounds/src/TestGrounds.fs b/src/FS.FluentUI.TestGrounds/src/TestGrounds.fs index 6dc4829..8c52d71 100644 --- a/src/FS.FluentUI.TestGrounds/src/TestGrounds.fs +++ b/src/FS.FluentUI.TestGrounds/src/TestGrounds.fs @@ -2961,7 +2961,7 @@ type ButtonItem = { [] let RenderButton (button: ButtonItem) (isLastItem: bool) = - React.fragment [ + React.Fragment [ Fui.overflowItem [ overflowItem.key (button.key |> string) overflowItem.priority (if isLastItem then button.key else 0) diff --git a/src/FS.FluentUI.TestGrounds/src/TestGrounds.fsproj b/src/FS.FluentUI.TestGrounds/src/TestGrounds.fsproj index d3c846b..51c3f26 100644 --- a/src/FS.FluentUI.TestGrounds/src/TestGrounds.fsproj +++ b/src/FS.FluentUI.TestGrounds/src/TestGrounds.fsproj @@ -4,6 +4,7 @@ Exe net8.0 + $(NoWarn);NU1605 @@ -40,8 +41,10 @@ - - + + + + diff --git a/src/FS.FluentUI.TestGrounds/src/index.html b/src/FS.FluentUI.TestGrounds/src/index.html index 0e0abb6..89643f9 100644 --- a/src/FS.FluentUI.TestGrounds/src/index.html +++ b/src/FS.FluentUI.TestGrounds/src/index.html @@ -14,7 +14,7 @@
- - + + From 20c5d878b8ae7dcbf22e632a35a6485b6306f131 Mon Sep 17 00:00:00 2001 From: Finn Olav Sagen Date: Sun, 5 Apr 2026 12:03:05 +0200 Subject: [PATCH 5/9] bump fullcalendar to fable.core 4.5 --- src/FS.FullCalendar/FS.FullCalendar.fsproj | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/FS.FullCalendar/FS.FullCalendar.fsproj b/src/FS.FullCalendar/FS.FullCalendar.fsproj index a5736f0..27f5c41 100644 --- a/src/FS.FullCalendar/FS.FullCalendar.fsproj +++ b/src/FS.FullCalendar/FS.FullCalendar.fsproj @@ -30,10 +30,11 @@ + - + From 92993cb327f4b2f799b9aac7badc7d9d41478b34 Mon Sep 17 00:00:00 2001 From: Finn Olav Sagen Date: Sun, 5 Apr 2026 18:42:57 +0200 Subject: [PATCH 6/9] add dotnet-tools.json --- .../.config/dotnet-tools.json | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 src/FS.FluentUI.TestGrounds/.config/dotnet-tools.json diff --git a/src/FS.FluentUI.TestGrounds/.config/dotnet-tools.json b/src/FS.FluentUI.TestGrounds/.config/dotnet-tools.json new file mode 100644 index 0000000..28af286 --- /dev/null +++ b/src/FS.FluentUI.TestGrounds/.config/dotnet-tools.json @@ -0,0 +1,18 @@ +{ + "version": 1, + "isRoot": true, + "tools": { + "fable": { + "version": "4.1.4", + "commands": [ + "fable" + ] + }, + "fantomas": { + "version": "6.1.3", + "commands": [ + "fantomas" + ] + } + } +} \ No newline at end of file From 016556d047f7440a8f1089c9c4ca3715e9aa557b Mon Sep 17 00:00:00 2001 From: Finn Olav Sagen Date: Sun, 5 Apr 2026 19:23:02 +0200 Subject: [PATCH 7/9] fable tool to 4.5.0 --- src/FS.FluentUI.TestGrounds/.config/dotnet-tools.json | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/FS.FluentUI.TestGrounds/.config/dotnet-tools.json b/src/FS.FluentUI.TestGrounds/.config/dotnet-tools.json index 28af286..dca240e 100644 --- a/src/FS.FluentUI.TestGrounds/.config/dotnet-tools.json +++ b/src/FS.FluentUI.TestGrounds/.config/dotnet-tools.json @@ -3,16 +3,18 @@ "isRoot": true, "tools": { "fable": { - "version": "4.1.4", + "version": "4.29.0", "commands": [ "fable" - ] + ], + "rollForward": false }, "fantomas": { "version": "6.1.3", "commands": [ "fantomas" - ] + ], + "rollForward": false } } } \ No newline at end of file From 48ee596dc7d1fa47ad17dd824f4c610f2aabb19f Mon Sep 17 00:00:00 2001 From: Finn Olav Sagen Date: Sun, 5 Apr 2026 19:24:01 +0200 Subject: [PATCH 8/9] Use Feliz.HtmlHelper.extractByKeyFast in FuiHelpers.createElement --- src/FS.FluentUI/FluentUI.fs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/FS.FluentUI/FluentUI.fs b/src/FS.FluentUI/FluentUI.fs index 5ee7f24..d222316 100644 --- a/src/FS.FluentUI/FluentUI.fs +++ b/src/FS.FluentUI/FluentUI.fs @@ -174,7 +174,12 @@ module FuiHelpers = let inline reactElement (el: ReactElementType) (props: 'a) : ReactElement = import "createElement" "react" - let inline createElement (el: ReactElementType) (props: 'ControlProperty list) : ReactElement = reactElement el (!!props |> createObj) + let inline createElement (el: ReactElementType) (props: 'ControlProperty list) : ReactElement = + match unbox<(string * obj) list> props |> Feliz.HtmlHelper.extractByKeyFast "children" with + | rest, Some (_, c) -> + emitJsExpr (import "createElement" "react", el, createObj rest, c) + "Array.isArray($3) ? $0($1, $2, ...$3) : $0($1, $2, $3)" + | rest, None -> reactElement el (createObj rest) let [] FluentUIv9 = "@fluentui/react-components" let [] FluentIcons = "@fluentui/react-icons" From 9d266dc8adcf89237248ae3d84b1fdffc70faea3 Mon Sep 17 00:00:00 2001 From: Finn Olav Sagen Date: Sun, 5 Apr 2026 20:07:20 +0200 Subject: [PATCH 9/9] Bump to fable 5 prerelease Update fable js api interaciton for bundleIcons --- src/FS.FluentUI.TestGrounds/.config/dotnet-tools.json | 2 +- src/FS.FluentUI.TestGrounds/src/TestCharts.fs | 2 +- src/FS.FluentUI.TestGrounds/src/TestGrounds.fsproj | 3 +-- src/FS.FluentUI/BundleIcons.fs | 9 ++++++--- src/FS.FluentUI/FluentUI.fs | 3 ++- 5 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/FS.FluentUI.TestGrounds/.config/dotnet-tools.json b/src/FS.FluentUI.TestGrounds/.config/dotnet-tools.json index dca240e..e8d07b9 100644 --- a/src/FS.FluentUI.TestGrounds/.config/dotnet-tools.json +++ b/src/FS.FluentUI.TestGrounds/.config/dotnet-tools.json @@ -3,7 +3,7 @@ "isRoot": true, "tools": { "fable": { - "version": "4.29.0", + "version": "5.0.0-rc.6", "commands": [ "fable" ], diff --git a/src/FS.FluentUI.TestGrounds/src/TestCharts.fs b/src/FS.FluentUI.TestGrounds/src/TestCharts.fs index 325265e..3da7dd4 100644 --- a/src/FS.FluentUI.TestGrounds/src/TestCharts.fs +++ b/src/FS.FluentUI.TestGrounds/src/TestCharts.fs @@ -851,7 +851,7 @@ let TestChartsComponent () = areaChart.height 300 areaChart.width 600 areaChart.legendsOverflowText "Overflow Items" - areaChart.yAxisTickFormat (fun (s:string) -> $"${s}") + areaChart.yAxisTickFormat (fun (s:string) -> "$" + s) areaChart.svgProps [ prop.ariaLabel "This is another test?!"] areaChart.enableGradient true areaChart.enablePerfOptimization true diff --git a/src/FS.FluentUI.TestGrounds/src/TestGrounds.fsproj b/src/FS.FluentUI.TestGrounds/src/TestGrounds.fsproj index 51c3f26..28c57eb 100644 --- a/src/FS.FluentUI.TestGrounds/src/TestGrounds.fsproj +++ b/src/FS.FluentUI.TestGrounds/src/TestGrounds.fsproj @@ -4,7 +4,6 @@ Exe net8.0 - $(NoWarn);NU1605 @@ -43,7 +42,7 @@ - + diff --git a/src/FS.FluentUI/BundleIcons.fs b/src/FS.FluentUI/BundleIcons.fs index a07238a..954f5d5 100644 --- a/src/FS.FluentUI/BundleIcons.fs +++ b/src/FS.FluentUI/BundleIcons.fs @@ -6,8 +6,9 @@ open FS.FluentUI type [] bundleHelper = static member inline expandImport (value : string) = - let filled = import $"{value}Filled" FluentIcons |> unbox - let regular = import $"{value}Regular" FluentIcons |> unbox + let icons : obj = importAll FluentIcons + let filled : BundleIcon = emitJsExpr (icons, value) "$0[$1 + 'Filled']" + let regular : BundleIcon = emitJsExpr (icons, value) "$0[$1 + 'Regular']" { BundleIcons.Filled = filled; BundleIcons.Regular = regular } @@ -28,7 +29,9 @@ type [] bundleIcons = ///} /// /// Fui.bundleIcon customBundleIcons - static member inline import (iconName: string) = import $"{iconName}" FluentIcons |> unbox + static member inline import (iconName: string) : BundleIcon = + let icons : obj = importAll FluentIcons + emitJsExpr (icons, iconName) "$0[$1]" static member inline xray = bundleHelper.expandImport "Xray" static member inline usbStick = bundleHelper.expandImport "UsbStick" static member inline usbPlug = bundleHelper.expandImport "UsbPlug" diff --git a/src/FS.FluentUI/FluentUI.fs b/src/FS.FluentUI/FluentUI.fs index d222316..2b783ee 100644 --- a/src/FS.FluentUI/FluentUI.fs +++ b/src/FS.FluentUI/FluentUI.fs @@ -1195,7 +1195,8 @@ module Fui = /// let icon = Fui.icon.import "BlockBusterLogoFilled" [] /// static member inline import (iconName: string) = - let icon = import $"{iconName}" FluentIcons + let icons : obj = importAll FluentIcons + let icon : ReactElementType = emitJsExpr (icons, iconName) "$0[$1]" fun (props: IIconProp list) -> createElement icon props /// Use this function to create new icons from SVG paths.