Bläddra i källkod

Bulma widgets

Michaël Van Canneyt 3 år sedan
förälder
incheckning
8fa57daec4
34 ändrade filer med 2217 tillägg och 0 borttagningar
  1. 11 0
      demo/design/README.md
  2. 0 0
      demo/design/bulmamodal/inline/bulma.min.css
  3. 108 0
      demo/design/bulmamodal/inline/bumodaldemo3.lpi
  4. 28 0
      demo/design/bulmamodal/inline/bumodaldemo3.lpr
  5. 39 0
      demo/design/bulmamodal/inline/dmindex.lfm
  6. 58 0
      demo/design/bulmamodal/inline/dmindex.pas
  7. 50 0
      demo/design/bulmamodal/inline/index.html
  8. 0 0
      demo/design/bulmamodal/loadtemplate/bulma.min.css
  9. 111 0
      demo/design/bulmamodal/loadtemplate/bumodaldemo2.lpi
  10. 28 0
      demo/design/bulmamodal/loadtemplate/bumodaldemo2.lpr
  11. 19 0
      demo/design/bulmamodal/loadtemplate/dialog.html
  12. 48 0
      demo/design/bulmamodal/loadtemplate/dmindex.lfm
  13. 68 0
      demo/design/bulmamodal/loadtemplate/dmindex.pas
  14. 34 0
      demo/design/bulmamodal/loadtemplate/index.html
  15. 0 0
      demo/design/bulmamodal/template/bulma.min.css
  16. 108 0
      demo/design/bulmamodal/template/bumodaldemo1.lpi
  17. 28 0
      demo/design/bulmamodal/template/bumodaldemo1.lpr
  18. 40 0
      demo/design/bulmamodal/template/dmindex.lfm
  19. 58 0
      demo/design/bulmamodal/template/dmindex.pas
  20. 33 0
      demo/design/bulmamodal/template/index.html
  21. 0 0
      demo/design/bulmamodal/values/bulma.min.css
  22. 111 0
      demo/design/bulmamodal/values/bumodaldemo2.lpi
  23. 28 0
      demo/design/bulmamodal/values/bumodaldemo2.lpr
  24. 23 0
      demo/design/bulmamodal/values/dialog.html
  25. 58 0
      demo/design/bulmamodal/values/dmindex.lfm
  26. 72 0
      demo/design/bulmamodal/values/dmindex.pas
  27. 37 0
      demo/design/bulmamodal/values/index.html
  28. 0 0
      demo/design/bulmatoast/bulma.min.css
  29. 106 0
      demo/design/bulmatoast/bulmatoast.lpi
  30. 12 0
      demo/design/bulmatoast/bulmatoast.lpr
  31. 29 0
      demo/design/bulmatoast/hfgindex.lfm
  32. 41 0
      demo/design/bulmatoast/hfgindex.pas
  33. 40 0
      demo/design/bulmatoast/index.html
  34. 791 0
      packages/bulma/bulmawidgets.pas

+ 11 - 0
demo/design/README.md

@@ -0,0 +1,11 @@
+## Bootstrap design-time components demos
+
+Bootstrap 5 is used, Bootstrap files are loaded from a CDN.
+
+## Bulma design-time component demos.
+
+Bulma does not need special Javascript files, only CSS.
+
+The bulma-toast example needs bulma-toast from
+
+https://github.com/rfoel/bulma-toast

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 0 - 0
demo/design/bulmamodal/inline/bulma.min.css


+ 108 - 0
demo/design/bulmamodal/inline/bumodaldemo3.lpi

@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<CONFIG>
+  <ProjectOptions>
+    <Version Value="12"/>
+    <General>
+      <Flags>
+        <SaveOnlyProjectUnits Value="True"/>
+        <MainUnitHasCreateFormStatements Value="False"/>
+        <MainUnitHasTitleStatement Value="False"/>
+        <MainUnitHasScaledStatement Value="False"/>
+        <Runnable Value="False"/>
+        <SaveJumpHistory Value="False"/>
+        <SaveFoldState Value="False"/>
+      </Flags>
+      <SessionStorage Value="InProjectDir"/>
+      <Title Value="modaldemo3"/>
+      <UseAppBundle Value="False"/>
+      <ResourceType Value="res"/>
+    </General>
+    <CustomData Count="6">
+      <Item0 Name="MaintainHTML" Value="1"/>
+      <Item1 Name="Pas2JSProject" Value="1"/>
+      <Item2 Name="PasJSHTMLFile" Value="project1.html"/>
+      <Item3 Name="PasJSLocation" Value="inlinebootstrap"/>
+      <Item4 Name="PasJSWebBrowserProject" Value="1"/>
+      <Item5 Name="RunAtReady" Value="1"/>
+    </CustomData>
+    <BuildModes>
+      <Item Name="Default" Default="True"/>
+    </BuildModes>
+    <PublishOptions>
+      <Version Value="2"/>
+      <UseFileFilters Value="True"/>
+    </PublishOptions>
+    <RunParams>
+      <FormatVersion Value="2"/>
+    </RunParams>
+    <RequiredPackages>
+      <Item>
+        <PackageName Value="pas2jscomponents"/>
+      </Item>
+    </RequiredPackages>
+    <Units>
+      <Unit>
+        <Filename Value="bumodaldemo3.lpr"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="modaldemo3"/>
+      </Unit>
+      <Unit>
+        <Filename Value="index.html"/>
+        <IsPartOfProject Value="True"/>
+        <CustomData Count="1">
+          <Item0 Name="PasJSIsProjectHTMLFile" Value="1"/>
+        </CustomData>
+      </Unit>
+      <Unit>
+        <Filename Value="dmindex.pas"/>
+        <IsPartOfProject Value="True"/>
+        <ComponentName Value="hfHello"/>
+        <HasResources Value="True"/>
+        <ResourceBaseClass Value="DataModule"/>
+      </Unit>
+    </Units>
+  </ProjectOptions>
+  <CompilerOptions>
+    <Version Value="11"/>
+    <Target FileExt=".js">
+      <Filename Value="modaldemo3"/>
+    </Target>
+    <SearchPaths>
+      <IncludeFiles Value="$(ProjOutDir)"/>
+      <UnitOutputDirectory Value="js"/>
+    </SearchPaths>
+    <Parsing>
+      <SyntaxOptions>
+        <AllowLabel Value="False"/>
+        <CPPInline Value="False"/>
+        <UseAnsiStrings Value="False"/>
+      </SyntaxOptions>
+    </Parsing>
+    <CodeGeneration>
+      <TargetOS Value="browser"/>
+    </CodeGeneration>
+    <Linking>
+      <Debugging>
+        <GenerateDebugInfo Value="False"/>
+        <UseLineInfoUnit Value="False"/>
+      </Debugging>
+    </Linking>
+    <Other>
+      <CustomOptions Value="-Jeutf-8 -Jirtl.js -Jc -Jminclude -JRjs"/>
+      <CompilerPath Value="$(pas2js)"/>
+    </Other>
+  </CompilerOptions>
+  <Debugging>
+    <Exceptions>
+      <Item>
+        <Name Value="EAbort"/>
+      </Item>
+      <Item>
+        <Name Value="ECodetoolError"/>
+      </Item>
+      <Item>
+        <Name Value="EFOpenError"/>
+      </Item>
+    </Exceptions>
+  </Debugging>
+</CONFIG>

+ 28 - 0
demo/design/bulmamodal/inline/bumodaldemo3.lpr

@@ -0,0 +1,28 @@
+program modaldemo3;
+
+{$mode objfpc}
+
+uses
+  browserapp, JS, Classes, SysUtils, Web, dmindex, p2jsres;
+
+type
+  TMyApplication = class(TBrowserApplication)
+    procedure doRun; override;
+  end;
+
+procedure TMyApplication.doRun;
+
+begin
+  With ThfHello.Create(Self) do
+    Show;
+  Terminate;
+end;
+
+var
+  Application : TMyApplication;
+
+begin
+  Application:=TMyApplication.Create(nil);
+  Application.Initialize;
+  Application.Run;
+end.

+ 39 - 0
demo/design/bulmamodal/inline/dmindex.lfm

@@ -0,0 +1,39 @@
+object hfHello: ThfHello
+  OldCreateOrder = False
+  UseProjectHTMLFile = True
+  OnHTMLLoaded = DataModuleHTMLLoaded
+  Height = 206
+  HorizontalOffset = 837
+  VerticalOffset = 356
+  Width = 424
+  object bmHello: TBulmaModal
+    ElementID = 'mdlDialog'
+    Styles = <>
+    StyleRefresh = srOnElementID
+    References = <    
+      item
+        Selector = '#btnSave'
+        Name = 'btnSave'
+        Kind = mikClose
+      end    
+      item
+        Selector = '#btnClose'
+        Name = 'btnClose'
+        Kind = mikClose
+      end>
+    RemoveOnHide = False
+    BackDrop = True
+    OnHide = bmHelloHide
+    Left = 64
+    Top = 40
+  end
+  object alMain: THTMLElementActionList
+    Left = 160
+    Top = 40
+    object actShowModal: THTMLElementAction
+      Events = [heClick]
+      ElementID = 'btnShowModal'
+      OnExecute = actShowModalExecute
+    end
+  end
+end

+ 58 - 0
demo/design/bulmamodal/inline/dmindex.pas

@@ -0,0 +1,58 @@
+unit dmindex;
+
+{$mode ObjFPC}
+
+interface
+
+uses
+  SysUtils, Classes, web, htmlfragment, bulmawidgets, Rtl.TemplateLoader,
+  Rtl.HTMLActions;
+
+type
+
+  { ThfHello }
+
+  ThfHello = class(THTMLFragment)
+    bmHello: TBulmaModal;
+    alMain: THTMLElementActionList;
+    actShowModal: THTMLElementAction;
+    procedure actShowModalExecute(Sender: TObject; Event: TJSEvent);
+    procedure bmHelloHide(Sender: TObject; El: TJSHTMLElement; Values: TStrings);
+    procedure DataModuleHTMLLoaded(Sender: TObject);
+  private
+  public
+
+  end;
+
+var
+  hfHello: ThfHello;
+
+implementation
+
+{$R *.lfm}
+
+{ ThfHello }
+
+
+procedure ThfHello.actShowModalExecute(Sender: TObject; Event: TJSEvent);
+begin
+  bmHello.show;
+end;
+
+procedure ThfHello.bmHelloHide(Sender: TObject; El: TJSHTMLElement;
+  Values: TStrings);
+begin
+  if Assigned(el) and SameText(el.id,'btnSave') then
+    window.alert('You confirmed the dialog with the save button')
+  else
+    window.alert('You canceled the dialog');
+
+end;
+
+procedure ThfHello.DataModuleHTMLLoaded(Sender: TObject);
+begin
+  alMain.Bind;
+end;
+
+end.
+

+ 50 - 0
demo/design/bulmamodal/inline/index.html

@@ -0,0 +1,50 @@
+<!doctype html>
+<html lang="en">
+<head>
+  <meta http-equiv="Content-type" content="text/html; charset=utf-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1">
+  <title>Bulma Modal demo (inline)</title>
+  <link href="bulma.min.css" rel="stylesheet"/>
+  <script  src="modaldemo3.js"></script>
+</head>
+<body>
+  <div class="hero">
+    <div class="hero-body">
+      <h2 class="title is-4">TBulmaModal demo</h2>
+      <p class="">This is simple demo where a <em>TBulmaModal</em> class is used to show a modal dialog.
+      The modal HTML is present in HTML page iself, and the property <em>ElementID</em> refers to it.</p>
+    </div>
+  </div>
+  <hr class="my-4">
+  <div id="modals-parent">
+    <div id="mdlDialog" class="modal" tabindex="-1">
+      <div class="modal-background"></div>
+      <div class="modal-card">
+        <div class="modal-card-head">
+          <p class="modal-card-title">Bulma modal demo</p>
+          <button type="button" class="delete" aria-label="Close"></button>
+        </div>
+        <div class="modal-card-body">
+           <h5 class="title is-5">Hello, World!</h5>
+           <p>Brought to you inline by <em>TBulmaModal</em>...</p>
+        </div>
+        <div class="modal-card-foot">
+          <button type="button" class="button" id="btnClose">Close</button>
+          <button type="button" class="button is-success" id="btnSave">Save changes</button>
+        </div>
+      </div>
+    </div>
+  </div>
+  <div class="box py-5">
+    <div class="is-flex is-justify-content-center">
+      <button id="btnShowModal" class="button is-primary">Show modal dialog</button>
+    </div>
+   </div>
+  <script>
+    rtl.showUncaughtExceptions=true;
+    window.addEventListener("load", rtl.run);
+  </script>
+
+  
+</body>
+</html>

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 0 - 0
demo/design/bulmamodal/loadtemplate/bulma.min.css


+ 111 - 0
demo/design/bulmamodal/loadtemplate/bumodaldemo2.lpi

@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<CONFIG>
+  <ProjectOptions>
+    <Version Value="12"/>
+    <General>
+      <Flags>
+        <SaveOnlyProjectUnits Value="True"/>
+        <MainUnitHasCreateFormStatements Value="False"/>
+        <MainUnitHasTitleStatement Value="False"/>
+        <MainUnitHasScaledStatement Value="False"/>
+        <Runnable Value="False"/>
+        <SaveJumpHistory Value="False"/>
+        <SaveFoldState Value="False"/>
+      </Flags>
+      <SessionStorage Value="InProjectDir"/>
+      <Title Value="bumodaldemo2"/>
+      <UseAppBundle Value="False"/>
+      <ResourceType Value="res"/>
+    </General>
+    <CustomData Count="6">
+      <Item0 Name="MaintainHTML" Value="1"/>
+      <Item1 Name="Pas2JSProject" Value="1"/>
+      <Item2 Name="PasJSHTMLFile" Value="project1.html"/>
+      <Item3 Name="PasJSPort" Value="3001"/>
+      <Item4 Name="PasJSWebBrowserProject" Value="1"/>
+      <Item5 Name="RunAtReady" Value="1"/>
+    </CustomData>
+    <BuildModes>
+      <Item Name="Default" Default="True"/>
+    </BuildModes>
+    <PublishOptions>
+      <Version Value="2"/>
+      <UseFileFilters Value="True"/>
+    </PublishOptions>
+    <RunParams>
+      <FormatVersion Value="2"/>
+    </RunParams>
+    <RequiredPackages>
+      <Item>
+        <PackageName Value="pas2jscomponents"/>
+      </Item>
+    </RequiredPackages>
+    <Units>
+      <Unit>
+        <Filename Value="bumodaldemo2.lpr"/>
+        <IsPartOfProject Value="True"/>
+      </Unit>
+      <Unit>
+        <Filename Value="index.html"/>
+        <IsPartOfProject Value="True"/>
+        <CustomData Count="1">
+          <Item0 Name="PasJSIsProjectHTMLFile" Value="1"/>
+        </CustomData>
+      </Unit>
+      <Unit>
+        <Filename Value="dmindex.pas"/>
+        <IsPartOfProject Value="True"/>
+        <ComponentName Value="hfHello"/>
+        <HasResources Value="True"/>
+        <ResourceBaseClass Value="DataModule"/>
+      </Unit>
+      <Unit>
+        <Filename Value="dialog.html"/>
+        <IsPartOfProject Value="True"/>
+      </Unit>
+    </Units>
+  </ProjectOptions>
+  <CompilerOptions>
+    <Version Value="11"/>
+    <Target FileExt=".js">
+      <Filename Value="bumodaldemo2"/>
+    </Target>
+    <SearchPaths>
+      <IncludeFiles Value="$(ProjOutDir)"/>
+      <UnitOutputDirectory Value="js"/>
+    </SearchPaths>
+    <Parsing>
+      <SyntaxOptions>
+        <AllowLabel Value="False"/>
+        <CPPInline Value="False"/>
+        <UseAnsiStrings Value="False"/>
+      </SyntaxOptions>
+    </Parsing>
+    <CodeGeneration>
+      <TargetOS Value="browser"/>
+    </CodeGeneration>
+    <Linking>
+      <Debugging>
+        <GenerateDebugInfo Value="False"/>
+        <UseLineInfoUnit Value="False"/>
+      </Debugging>
+    </Linking>
+    <Other>
+      <CustomOptions Value="-Jeutf-8 -Jirtl.js -Jc -Jminclude -JRjs"/>
+      <CompilerPath Value="$(pas2js)"/>
+    </Other>
+  </CompilerOptions>
+  <Debugging>
+    <Exceptions>
+      <Item>
+        <Name Value="EAbort"/>
+      </Item>
+      <Item>
+        <Name Value="ECodetoolError"/>
+      </Item>
+      <Item>
+        <Name Value="EFOpenError"/>
+      </Item>
+    </Exceptions>
+  </Debugging>
+</CONFIG>

+ 28 - 0
demo/design/bulmamodal/loadtemplate/bumodaldemo2.lpr

@@ -0,0 +1,28 @@
+program bumodaldemo2;
+
+{$mode objfpc}
+
+uses
+  browserapp, JS, Classes, SysUtils, Web, dmindex, p2jsres;
+
+type
+  TMyApplication = class(TBrowserApplication)
+    procedure doRun; override;
+  end;
+
+procedure TMyApplication.doRun;
+
+begin
+  with ThfHello.Create(Self) do
+    Show;
+  Terminate;
+end;
+
+var
+  Application : TMyApplication;
+
+begin
+  Application:=TMyApplication.Create(nil);
+  Application.Initialize;
+  Application.Run;
+end.

+ 19 - 0
demo/design/bulmamodal/loadtemplate/dialog.html

@@ -0,0 +1,19 @@
+    <div class="modal" tabindex="-1">
+      <div class="modal-background"></div>
+      <div class="modal-card">
+        <div class="modal-card-head">
+          <p class="modal-card-title">Bulma modal demo</p>
+          <button type="button" class="delete" aria-label="Close"></button>
+        </div>
+        <div class="modal-card-body">
+           <h5 class="title is-5">Hello, World!</h5>
+           <p>Brought to you inline by <em>TBulmaModal</em>...</p>
+        </div>
+        <div class="modal-card-foot">
+          <button type="button" class="button" id="btnClose">Close</button>
+          <button type="button" class="button is-success" id="btnSave">Save changes</button>
+        </div>
+      </div>
+    </div>
+
+

+ 48 - 0
demo/design/bulmamodal/loadtemplate/dmindex.lfm

@@ -0,0 +1,48 @@
+object hfHello: ThfHello
+  OldCreateOrder = False
+  UseProjectHTMLFile = True
+  OnHTMLLoaded = DataModuleHTMLLoaded
+  Height = 206
+  HorizontalOffset = 538
+  VerticalOffset = 312
+  Width = 424
+  object bmHello: TBulmaModal
+    ParentID = 'modals-parent'
+    Styles = <>
+    StyleRefresh = srOnElementID
+    ShowOnRender = False
+    BackDrop = True
+    KeyBoard = False
+    Focus = False
+    TemplateName = 'dialog'
+    TemplateLoader = tlDialogs
+    OnHide = bmHelloHide
+    References = <    
+      item
+        Selector = '#btnSave'
+        Name = 'btnSave'
+        Kind = mikClose
+      end>
+    Left = 64
+    Top = 40
+  end
+  object alMain: THTMLElementActionList
+    Left = 160
+    Top = 40
+    object actShowModal: THTMLElementAction
+      Events = [heClick]
+      ElementID = 'btnShowModal'
+      OnExecute = actShowModalExecute
+    end
+  end
+  object tlDialogs: TTemplateLoader
+    CheckResources = False
+    PreloadTemplates = <    
+      item
+        Name = 'dialog'
+        HTMLFile = 'dialog.html'
+      end>
+    Left = 80
+    Top = 103
+  end
+end

+ 68 - 0
demo/design/bulmamodal/loadtemplate/dmindex.pas

@@ -0,0 +1,68 @@
+unit dmindex;
+
+{$mode ObjFPC}
+
+interface
+
+uses
+  SysUtils, Classes, web, htmlfragment, bulmawidgets, Rtl.TemplateLoader,
+  Rtl.HTMLActions;
+
+type
+
+  { ThfHello }
+
+  ThfHello = class(THTMLFragment)
+    bmHello: TBulmaModal;
+    alMain: THTMLElementActionList;
+    actShowModal: THTMLElementAction;
+    tlDialogs: TTemplateLoader;
+    procedure actShowModalExecute(Sender: TObject; Event: TJSEvent);
+    procedure alMainExecute(Sender: TObject; Event: TJSEvent;
+      var Handled: Boolean);
+    procedure bmHelloHide(Sender: TObject; El: TJSHTMLElement; Values: TStrings
+      );
+    procedure DataModuleHTMLLoaded(Sender: TObject);
+  private
+  public
+
+  end;
+
+var
+  hfHello: ThfHello;
+
+implementation
+
+{$R *.lfm}
+
+{ ThfHello }
+
+
+procedure ThfHello.actShowModalExecute(Sender: TObject; Event: TJSEvent);
+begin
+  bmHello.show;
+end;
+
+procedure ThfHello.alMainExecute(Sender: TObject; Event: TJSEvent;
+  var Handled: Boolean);
+begin
+
+end;
+
+procedure ThfHello.bmHelloHide(Sender: TObject; El: TJSHTMLElement;
+  Values: TStrings);
+begin
+  if Assigned(el) and SameText(el.id,'btnSave') then
+    window.alert('You confirmed the dialog with the save button')
+  else
+    window.alert('You canceled the dialog');
+
+end;
+
+procedure ThfHello.DataModuleHTMLLoaded(Sender: TObject);
+begin
+  alMain.Bind;
+end;
+
+end.
+

+ 34 - 0
demo/design/bulmamodal/loadtemplate/index.html

@@ -0,0 +1,34 @@
+<!doctype html>
+<html lang="en">
+<head>
+  <meta http-equiv="Content-type" content="text/html; charset=utf-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1">
+  <title>Bulma Modal demo</title>
+  <link href="bulma.min.css" rel="stylesheet"/>
+  <script  src="bumodaldemo2.js"></script>
+</head>
+<body>
+  <div class="hero">
+    <div class="hero-body">
+      <h2 class="title is-4">TBulmaModal demo</h2>
+      <p class="">This is simple demo where a <em>TBulmaModal</em> class is used to show a modal
+      dialog.<br />
+      The modal HTML is loaded using a template loader.</p>
+    </div>
+  </div>
+  <hr class="my-4">
+  <div id="modals-parent">
+  </div>
+  <div class="box py-5">
+    <div class="is-flex is-justify-content-center">
+      <button id="btnShowModal" class="button is-primary">Show modal dialog</button>
+    </div>
+   </div>
+  <script>
+    rtl.showUncaughtExceptions=true;
+    window.addEventListener("load", rtl.run);
+  </script>
+
+  
+</body>
+</html>

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 0 - 0
demo/design/bulmamodal/template/bulma.min.css


+ 108 - 0
demo/design/bulmamodal/template/bumodaldemo1.lpi

@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<CONFIG>
+  <ProjectOptions>
+    <Version Value="12"/>
+    <General>
+      <Flags>
+        <SaveOnlyProjectUnits Value="True"/>
+        <MainUnitHasCreateFormStatements Value="False"/>
+        <MainUnitHasTitleStatement Value="False"/>
+        <MainUnitHasScaledStatement Value="False"/>
+        <Runnable Value="False"/>
+        <SaveJumpHistory Value="False"/>
+        <SaveFoldState Value="False"/>
+      </Flags>
+      <SessionStorage Value="InProjectDir"/>
+      <Title Value="modaldemo3"/>
+      <UseAppBundle Value="False"/>
+      <ResourceType Value="res"/>
+    </General>
+    <CustomData Count="6">
+      <Item0 Name="MaintainHTML" Value="1"/>
+      <Item1 Name="Pas2JSProject" Value="1"/>
+      <Item2 Name="PasJSHTMLFile" Value="project1.html"/>
+      <Item3 Name="PasJSLocation" Value="bulmamodaltemplate"/>
+      <Item4 Name="PasJSWebBrowserProject" Value="1"/>
+      <Item5 Name="RunAtReady" Value="1"/>
+    </CustomData>
+    <BuildModes>
+      <Item Name="Default" Default="True"/>
+    </BuildModes>
+    <PublishOptions>
+      <Version Value="2"/>
+      <UseFileFilters Value="True"/>
+    </PublishOptions>
+    <RunParams>
+      <FormatVersion Value="2"/>
+    </RunParams>
+    <RequiredPackages>
+      <Item>
+        <PackageName Value="pas2jscomponents"/>
+      </Item>
+    </RequiredPackages>
+    <Units>
+      <Unit>
+        <Filename Value="bumodaldemo1.lpr"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="modaldemo1"/>
+      </Unit>
+      <Unit>
+        <Filename Value="index.html"/>
+        <IsPartOfProject Value="True"/>
+        <CustomData Count="1">
+          <Item0 Name="PasJSIsProjectHTMLFile" Value="1"/>
+        </CustomData>
+      </Unit>
+      <Unit>
+        <Filename Value="dmindex.pas"/>
+        <IsPartOfProject Value="True"/>
+        <ComponentName Value="hfHello"/>
+        <HasResources Value="True"/>
+        <ResourceBaseClass Value="DataModule"/>
+      </Unit>
+    </Units>
+  </ProjectOptions>
+  <CompilerOptions>
+    <Version Value="11"/>
+    <Target FileExt=".js">
+      <Filename Value="bumodaldemo1"/>
+    </Target>
+    <SearchPaths>
+      <IncludeFiles Value="$(ProjOutDir)"/>
+      <UnitOutputDirectory Value="js"/>
+    </SearchPaths>
+    <Parsing>
+      <SyntaxOptions>
+        <AllowLabel Value="False"/>
+        <CPPInline Value="False"/>
+        <UseAnsiStrings Value="False"/>
+      </SyntaxOptions>
+    </Parsing>
+    <CodeGeneration>
+      <TargetOS Value="browser"/>
+    </CodeGeneration>
+    <Linking>
+      <Debugging>
+        <GenerateDebugInfo Value="False"/>
+        <UseLineInfoUnit Value="False"/>
+      </Debugging>
+    </Linking>
+    <Other>
+      <CustomOptions Value="-Jeutf-8 -Jirtl.js -Jc -Jminclude -JRjs"/>
+      <CompilerPath Value="$(pas2js)"/>
+    </Other>
+  </CompilerOptions>
+  <Debugging>
+    <Exceptions>
+      <Item>
+        <Name Value="EAbort"/>
+      </Item>
+      <Item>
+        <Name Value="ECodetoolError"/>
+      </Item>
+      <Item>
+        <Name Value="EFOpenError"/>
+      </Item>
+    </Exceptions>
+  </Debugging>
+</CONFIG>

+ 28 - 0
demo/design/bulmamodal/template/bumodaldemo1.lpr

@@ -0,0 +1,28 @@
+program bumodaldemo1;
+
+{$mode objfpc}
+
+uses
+  browserapp, JS, Classes, SysUtils, Web, dmindex, p2jsres;
+
+type
+  TMyApplication = class(TBrowserApplication)
+    procedure doRun; override;
+  end;
+
+procedure TMyApplication.doRun;
+
+begin
+  With ThfHello.Create(Self) do
+    Show;
+  Terminate;
+end;
+
+var
+  Application : TMyApplication;
+
+begin
+  Application:=TMyApplication.Create(nil);
+  Application.Initialize;
+  Application.Run;
+end.

+ 40 - 0
demo/design/bulmamodal/template/dmindex.lfm

@@ -0,0 +1,40 @@
+object hfHello: ThfHello
+  OldCreateOrder = False
+  UseProjectHTMLFile = True
+  OnHTMLLoaded = DataModuleHTMLLoaded
+  Height = 206
+  HorizontalOffset = 837
+  VerticalOffset = 356
+  Width = 424
+  object bmHello: TBulmaModal
+    ParentID = 'modals-parent'
+    Styles = <>
+    StyleRefresh = srOnElementID
+    References = <    
+      item
+        Selector = '#btnSave'
+        Name = 'btnSave'
+        Kind = mikClose
+      end    
+      item
+        Selector = '#btnClose'
+        Name = 'btnClose'
+        Kind = mikClose
+      end>
+    RemoveOnHide = False
+    BackDrop = True
+    Template = '    <div  class="modal" tabindex="-1">'#10'      <div class="modal-background"></div>'#10'      <div class="modal-card">'#10'        <div class="modal-card-head">'#10'          <p class="modal-card-title">Bulma modal demo</p>'#10'          <button type="button" class="delete" aria-label="Close"></button>'#10'        </div>'#10'        <div class="modal-card-body">'#10'           <h5 class="title is-5">Hello, World!</h5>'#10'           <p>Brought to you from property <em>Template</em> by <em>TBulmaModal</em>...</p>'#10'        </div>'#10'        <div class="modal-card-foot">'#10'          <button type="button" class="button" id="btnClose">Close</button>'#10'          <button type="button" class="button is-success" id="btnSave">Save changes</button>'#10'        </div>'#10'      </div>'#10'    </div>'#10#10#10
+    OnHide = bmHelloHide
+    Left = 64
+    Top = 40
+  end
+  object alMain: THTMLElementActionList
+    Left = 160
+    Top = 40
+    object actShowModal: THTMLElementAction
+      Events = [heClick]
+      ElementID = 'btnShowModal'
+      OnExecute = actShowModalExecute
+    end
+  end
+end

+ 58 - 0
demo/design/bulmamodal/template/dmindex.pas

@@ -0,0 +1,58 @@
+unit dmindex;
+
+{$mode ObjFPC}
+
+interface
+
+uses
+  SysUtils, Classes, web, htmlfragment, bulmawidgets, Rtl.TemplateLoader,
+  Rtl.HTMLActions;
+
+type
+
+  { ThfHello }
+
+  ThfHello = class(THTMLFragment)
+    bmHello: TBulmaModal;
+    alMain: THTMLElementActionList;
+    actShowModal: THTMLElementAction;
+    procedure actShowModalExecute(Sender: TObject; Event: TJSEvent);
+    procedure bmHelloHide(Sender: TObject; El: TJSHTMLElement; Values: TStrings);
+    procedure DataModuleHTMLLoaded(Sender: TObject);
+  private
+  public
+
+  end;
+
+var
+  hfHello: ThfHello;
+
+implementation
+
+{$R *.lfm}
+
+{ ThfHello }
+
+
+procedure ThfHello.actShowModalExecute(Sender: TObject; Event: TJSEvent);
+begin
+  bmHello.show;
+end;
+
+procedure ThfHello.bmHelloHide(Sender: TObject; El: TJSHTMLElement;
+  Values: TStrings);
+begin
+  if Assigned(el) and SameText(el.id,'btnSave') then
+    window.alert('You confirmed the dialog with the save button')
+  else
+    window.alert('You canceled the dialog');
+
+end;
+
+procedure ThfHello.DataModuleHTMLLoaded(Sender: TObject);
+begin
+  alMain.Bind;
+end;
+
+end.
+

+ 33 - 0
demo/design/bulmamodal/template/index.html

@@ -0,0 +1,33 @@
+<!doctype html>
+<html lang="en">
+<head>
+  <meta http-equiv="Content-type" content="text/html; charset=utf-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1">
+  <title>Bulma Modal demo (template)</title>
+  <link href="bulma.min.css" rel="stylesheet"/>
+  <script  src="bumodaldemo1.js"></script>
+</head>
+<body>
+  <div class="hero">
+    <div class="hero-body">
+      <h2 class="title is-4">TBulmaModal demo</h2>
+      <p class="">This is simple demo where a <em>TBulmaModal</em> class is used to show a modal dialog.<br />
+      The modal HTML is specified in the <em>Template</em> property, and the property <em>ParentID</em> specifies where the dialog is rendered</p>
+    </div>
+  </div>
+  <hr class="my-4">
+  <div id="modals-parent">
+  </div>
+  <div class="box py-5">
+    <div class="is-flex is-justify-content-center">
+      <button id="btnShowModal" class="button is-primary">Show modal dialog</button>
+    </div>
+   </div>
+  <script>
+    rtl.showUncaughtExceptions=true;
+    window.addEventListener("load", rtl.run);
+  </script>
+
+  
+</body>
+</html>

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 0 - 0
demo/design/bulmamodal/values/bulma.min.css


+ 111 - 0
demo/design/bulmamodal/values/bumodaldemo2.lpi

@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<CONFIG>
+  <ProjectOptions>
+    <Version Value="12"/>
+    <General>
+      <Flags>
+        <SaveOnlyProjectUnits Value="True"/>
+        <MainUnitHasCreateFormStatements Value="False"/>
+        <MainUnitHasTitleStatement Value="False"/>
+        <MainUnitHasScaledStatement Value="False"/>
+        <Runnable Value="False"/>
+        <SaveJumpHistory Value="False"/>
+        <SaveFoldState Value="False"/>
+      </Flags>
+      <SessionStorage Value="InProjectDir"/>
+      <Title Value="Bulma modal demo (values)"/>
+      <UseAppBundle Value="False"/>
+      <ResourceType Value="res"/>
+    </General>
+    <CustomData Count="6">
+      <Item0 Name="MaintainHTML" Value="1"/>
+      <Item1 Name="Pas2JSProject" Value="1"/>
+      <Item2 Name="PasJSHTMLFile" Value="project1.html"/>
+      <Item3 Name="PasJSLocation" Value="modal-values"/>
+      <Item4 Name="PasJSWebBrowserProject" Value="1"/>
+      <Item5 Name="RunAtReady" Value="1"/>
+    </CustomData>
+    <BuildModes>
+      <Item Name="Default" Default="True"/>
+    </BuildModes>
+    <PublishOptions>
+      <Version Value="2"/>
+      <UseFileFilters Value="True"/>
+    </PublishOptions>
+    <RunParams>
+      <FormatVersion Value="2"/>
+    </RunParams>
+    <RequiredPackages>
+      <Item>
+        <PackageName Value="pas2jscomponents"/>
+      </Item>
+    </RequiredPackages>
+    <Units>
+      <Unit>
+        <Filename Value="bumodaldemo2.lpr"/>
+        <IsPartOfProject Value="True"/>
+      </Unit>
+      <Unit>
+        <Filename Value="index.html"/>
+        <IsPartOfProject Value="True"/>
+        <CustomData Count="1">
+          <Item0 Name="PasJSIsProjectHTMLFile" Value="1"/>
+        </CustomData>
+      </Unit>
+      <Unit>
+        <Filename Value="dmindex.pas"/>
+        <IsPartOfProject Value="True"/>
+        <ComponentName Value="hfHello"/>
+        <HasResources Value="True"/>
+        <ResourceBaseClass Value="DataModule"/>
+      </Unit>
+      <Unit>
+        <Filename Value="dialog.html"/>
+        <IsPartOfProject Value="True"/>
+      </Unit>
+    </Units>
+  </ProjectOptions>
+  <CompilerOptions>
+    <Version Value="11"/>
+    <Target FileExt=".js">
+      <Filename Value="bumodaldemo2"/>
+    </Target>
+    <SearchPaths>
+      <IncludeFiles Value="$(ProjOutDir)"/>
+      <UnitOutputDirectory Value="js"/>
+    </SearchPaths>
+    <Parsing>
+      <SyntaxOptions>
+        <AllowLabel Value="False"/>
+        <CPPInline Value="False"/>
+        <UseAnsiStrings Value="False"/>
+      </SyntaxOptions>
+    </Parsing>
+    <CodeGeneration>
+      <TargetOS Value="browser"/>
+    </CodeGeneration>
+    <Linking>
+      <Debugging>
+        <GenerateDebugInfo Value="False"/>
+        <UseLineInfoUnit Value="False"/>
+      </Debugging>
+    </Linking>
+    <Other>
+      <CustomOptions Value="-Jeutf-8 -Jirtl.js -Jc -Jminclude -JRjs"/>
+      <CompilerPath Value="$(pas2js)"/>
+    </Other>
+  </CompilerOptions>
+  <Debugging>
+    <Exceptions>
+      <Item>
+        <Name Value="EAbort"/>
+      </Item>
+      <Item>
+        <Name Value="ECodetoolError"/>
+      </Item>
+      <Item>
+        <Name Value="EFOpenError"/>
+      </Item>
+    </Exceptions>
+  </Debugging>
+</CONFIG>

+ 28 - 0
demo/design/bulmamodal/values/bumodaldemo2.lpr

@@ -0,0 +1,28 @@
+program bumodaldemo2;
+
+{$mode objfpc}
+
+uses
+  browserapp, JS, Classes, SysUtils, Web, dmindex, p2jsres;
+
+type
+  TMyApplication = class(TBrowserApplication)
+    procedure doRun; override;
+  end;
+
+procedure TMyApplication.doRun;
+
+begin
+  with ThfHello.Create(Self) do
+    Show;
+  Terminate;
+end;
+
+var
+  Application : TMyApplication;
+
+begin
+  Application:=TMyApplication.Create(nil);
+  Application.Initialize;
+  Application.Run;
+end.

+ 23 - 0
demo/design/bulmamodal/values/dialog.html

@@ -0,0 +1,23 @@
+<div class="modal" tabindex="-1">
+  <div class="modal-background"></div>
+  <div class="modal-card">
+    <div class="modal-card-head">
+      <p class="modal-card-title">Bulma modal demo</p>
+      <button type="button" class="delete" aria-label="Close"></button>
+    </div>
+    <div class="modal-card-body">
+      <div class="field">
+        <label class="label" for="edtModalFirstName">First name</label>
+        <input type="text" class="input" id="edtModalFirstName" placeholder="Enter your first name">
+      </div>
+      <div class="field">
+        <label class="label" for="edtModalLastName">Last name</label>
+        <input type="text" class="input" id="edtModalLastName" placeholder="Enter your last name">
+      </div>
+    </div>
+    <div class="modal-card-foot">
+      <button type="button" class="button" id="btnClose">Close</button>
+      <button type="button" class="button is-success" id="btnSave">Save changes</button>
+    </div>
+  </div>
+</div>

+ 58 - 0
demo/design/bulmamodal/values/dmindex.lfm

@@ -0,0 +1,58 @@
+object hfHello: ThfHello
+  OldCreateOrder = False
+  UseProjectHTMLFile = True
+  OnHTMLLoaded = DataModuleHTMLLoaded
+  Height = 206
+  HorizontalOffset = 837
+  VerticalOffset = 356
+  Width = 424
+  object bmHello: TBulmaModal
+    ParentID = 'modals-parent'
+    Styles = <>
+    StyleRefresh = srOnElementID
+    ShowOnRender = False
+    BackDrop = True
+    KeyBoard = False
+    Focus = False
+    TemplateName = 'dialog'
+    TemplateLoader = tlDialogs
+    OnHide = bmHelloHide
+    References = <    
+      item
+        Selector = '#btnSave'
+        Name = 'btnSave'
+        Kind = mikClose
+      end    
+      item
+        Selector = '#edtModalFirstName'
+        Name = 'FirstName'
+        Kind = mikValue
+      end    
+      item
+        Selector = '#edtModalLastName'
+        Name = 'LastName'
+        Kind = mikValue
+      end>
+    Left = 64
+    Top = 40
+  end
+  object alMain: THTMLElementActionList
+    Left = 160
+    Top = 40
+    object actShowModal: THTMLElementAction
+      Events = [heClick]
+      ElementID = 'btnShowModal'
+      OnExecute = actShowModalExecute
+    end
+  end
+  object tlDialogs: TTemplateLoader
+    CheckResources = False
+    PreloadTemplates = <    
+      item
+        Name = 'dialog'
+        HTMLFile = 'dialog.html'
+      end>
+    Left = 80
+    Top = 103
+  end
+end

+ 72 - 0
demo/design/bulmamodal/values/dmindex.pas

@@ -0,0 +1,72 @@
+unit dmindex;
+
+{$mode ObjFPC}
+
+interface
+
+uses
+  SysUtils, Classes, web, htmlfragment, bulmawidgets, Rtl.TemplateLoader,
+  Rtl.HTMLActions;
+
+type
+
+  { ThfHello }
+
+  ThfHello = class(THTMLFragment)
+    bmHello: TBulmaModal;
+    alMain: THTMLElementActionList;
+    actShowModal: THTMLElementAction;
+    tlDialogs: TTemplateLoader;
+    procedure actShowModalExecute(Sender: TObject; Event: TJSEvent);
+    procedure bmHelloHide(Sender: TObject; El: TJSHTMLElement; Values: TStrings
+      );
+    procedure DataModuleHTMLLoaded(Sender: TObject);
+  private
+  public
+
+  end;
+
+var
+  hfHello: ThfHello;
+
+implementation
+
+{$R *.lfm}
+
+{ ThfHello }
+
+
+procedure ThfHello.actShowModalExecute(Sender: TObject; Event: TJSEvent);
+begin
+  bmHello.show;
+end;
+
+procedure ThfHello.bmHelloHide(Sender: TObject; El: TJSHTMLElement;
+  Values: TStrings);
+
+Var
+  aName,aFirstname,aLastName : String;
+
+begin
+  if Assigned(el) and SameText(el.id,'btnSave') then
+    begin
+    aFirstName:=Values.Values['FirstName'];
+    aLastName:=Values.Values['LastName'];
+    if (aFirstName='') and (aLastName='') then
+      aName:='Anonymous person'
+    else
+      aName:=aFirstName+' '+aLastName;
+    window.alert(aName+', you confirmed the dialog with the save button')
+    end
+  else
+    window.alert('You canceled the dialog');
+
+end;
+
+procedure ThfHello.DataModuleHTMLLoaded(Sender: TObject);
+begin
+  alMain.Bind;
+end;
+
+end.
+

+ 37 - 0
demo/design/bulmamodal/values/index.html

@@ -0,0 +1,37 @@
+<!doctype html>
+<html lang="en">
+<head>
+  <meta http-equiv="Content-type" content="text/html; charset=utf-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1">
+  <title>Bulma Modal demo</title>
+  <link href="bulma.min.css" rel="stylesheet"/>
+  <script  src="bumodaldemo2.js"></script>
+</head>
+<body>
+  <div class="hero">
+    <div class="hero-body">
+      <h2 class="title is-4">TBulmaModal demo</h2>
+      <p class="">This is simple demo where a <em>TBulmaModal</em> class is used to show a modal
+      dialog.<br />
+      The modal HTML is loaded using a template loader.</p>
+      <p>The modal dialog contains some input elements, the values of these can be retrieved by defining the elements
+      through the <var>References</var> collection: all values for references with <em>Kind=mikValue</em> will be collected and passed on in the <em>OnHide</em> event.
+      </p>
+    </div>
+  </div>
+  <hr class="my-4">
+  <div id="modals-parent">
+  </div>
+  <div class="box py-5">
+    <div class="is-flex is-justify-content-center">
+      <button id="btnShowModal" class="button is-primary">Show modal dialog</button>
+    </div>
+   </div>
+  <script>
+    rtl.showUncaughtExceptions=true;
+    window.addEventListener("load", rtl.run);
+  </script>
+
+  
+</body>
+</html>

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 0 - 0
demo/design/bulmatoast/bulma.min.css


+ 106 - 0
demo/design/bulmatoast/bulmatoast.lpi

@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<CONFIG>
+  <ProjectOptions>
+    <Version Value="12"/>
+    <General>
+      <Flags>
+        <SaveOnlyProjectUnits Value="True"/>
+        <MainUnitHasCreateFormStatements Value="False"/>
+        <MainUnitHasTitleStatement Value="False"/>
+        <MainUnitHasScaledStatement Value="False"/>
+        <SaveJumpHistory Value="False"/>
+        <SaveFoldState Value="False"/>
+      </Flags>
+      <SessionStorage Value="InProjectDir"/>
+      <Title Value="bulmatoast"/>
+      <UseAppBundle Value="False"/>
+      <ResourceType Value="res"/>
+    </General>
+    <CustomData Count="5">
+      <Item0 Name="MaintainHTML" Value="1"/>
+      <Item1 Name="Pas2JSProject" Value="1"/>
+      <Item2 Name="PasJSLocation" Value="$NameOnly($(ProjFile))"/>
+      <Item3 Name="PasJSWebBrowserProject" Value="1"/>
+      <Item4 Name="RunAtReady" Value="1"/>
+    </CustomData>
+    <BuildModes>
+      <Item Name="Default" Default="True"/>
+    </BuildModes>
+    <PublishOptions>
+      <Version Value="2"/>
+      <UseFileFilters Value="True"/>
+    </PublishOptions>
+    <RunParams>
+      <FormatVersion Value="2"/>
+    </RunParams>
+    <RequiredPackages>
+      <Item>
+        <PackageName Value="pas2jscomponents"/>
+      </Item>
+    </RequiredPackages>
+    <Units>
+      <Unit>
+        <Filename Value="bulmatoast.lpr"/>
+        <IsPartOfProject Value="True"/>
+      </Unit>
+      <Unit>
+        <Filename Value="index.html"/>
+        <IsPartOfProject Value="True"/>
+        <CustomData Count="1">
+          <Item0 Name="PasJSIsProjectHTMLFile" Value="1"/>
+        </CustomData>
+      </Unit>
+      <Unit>
+        <Filename Value="hfgindex.pas"/>
+        <IsPartOfProject Value="True"/>
+        <ComponentName Value="frgmIndex"/>
+        <HasResources Value="True"/>
+        <ResourceBaseClass Value="DataModule"/>
+        <UnitName Value="hfgIndex"/>
+      </Unit>
+    </Units>
+  </ProjectOptions>
+  <CompilerOptions>
+    <Version Value="11"/>
+    <Target FileExt=".js">
+      <Filename Value="bulmatoast"/>
+    </Target>
+    <SearchPaths>
+      <IncludeFiles Value="$(ProjOutDir)"/>
+      <UnitOutputDirectory Value="js"/>
+    </SearchPaths>
+    <Parsing>
+      <SyntaxOptions>
+        <AllowLabel Value="False"/>
+        <CPPInline Value="False"/>
+        <UseAnsiStrings Value="False"/>
+      </SyntaxOptions>
+    </Parsing>
+    <CodeGeneration>
+      <TargetOS Value="browser"/>
+    </CodeGeneration>
+    <Linking>
+      <Debugging>
+        <GenerateDebugInfo Value="False"/>
+        <UseLineInfoUnit Value="False"/>
+      </Debugging>
+    </Linking>
+    <Other>
+      <CustomOptions Value="-Jeutf-8 -Jirtl.js -Jc -Jminclude -JRjs"/>
+      <CompilerPath Value="$(pas2js)"/>
+    </Other>
+  </CompilerOptions>
+  <Debugging>
+    <Exceptions>
+      <Item>
+        <Name Value="EAbort"/>
+      </Item>
+      <Item>
+        <Name Value="ECodetoolError"/>
+      </Item>
+      <Item>
+        <Name Value="EFOpenError"/>
+      </Item>
+    </Exceptions>
+  </Debugging>
+</CONFIG>

+ 12 - 0
demo/design/bulmatoast/bulmatoast.lpr

@@ -0,0 +1,12 @@
+program bulmatoast;
+
+{$mode objfpc}
+
+uses
+  JS, Classes, SysUtils, Web, hfgIndex, p2jsres;
+
+begin
+  SetResourceSource(rsJS);
+  With TfrgmIndex.Create(Nil) do
+    Show;
+end.

+ 29 - 0
demo/design/bulmatoast/hfgindex.lfm

@@ -0,0 +1,29 @@
+object frgmIndex: TfrgmIndex
+  OldCreateOrder = False
+  UseProjectHTMLFile = True
+  Height = 222
+  HorizontalOffset = 699
+  VerticalOffset = 336
+  Width = 380
+  object btwDemo: TBulmaToastWidget
+    ParentID = 'toast-parent'
+    Header = 'Oh my Pas2JS!'
+    Body = '<p><strong>This must be a pas2js generated Toast!</strong></p><small>And it will disappear in 5 seconds...</small> '
+    CloseButton = True
+    Contextual = cDanger
+    HideDelay = 5000
+    Single = False
+    Position = tpTopCenter
+    Left = 168
+    Top = 32
+  end
+  object alIndex: THTMLElementActionList
+    Left = 64
+    Top = 25
+    object actShowToast: THTMLElementAction
+      Events = [heClick]
+      ElementID = 'btnShowToast'
+      OnExecute = actShowToastExecute
+    end
+  end
+end

+ 41 - 0
demo/design/bulmatoast/hfgindex.pas

@@ -0,0 +1,41 @@
+unit hfgIndex;
+
+{$mode ObjFPC}
+
+interface
+
+uses
+  SysUtils, Classes, Rtl.HTMLActions, htmlfragment, bulmawidgets, Web;
+
+type
+
+  { TfrgmIndex }
+
+  TfrgmIndex = class(THTMLFragment)
+    btwDemo: TBulmaToastWidget;
+    actShowToast: THTMLElementAction;
+    alIndex: THTMLElementActionList;
+    procedure actShowToastExecute(Sender: TObject; Event: TJSEvent);
+  private
+
+  public
+
+  end;
+
+var
+  frgmIndex: TfrgmIndex;
+
+implementation
+
+{$R *.lfm}
+
+{ TfrgmIndex }
+
+procedure TfrgmIndex.actShowToastExecute(Sender: TObject;
+  Event: TJSEvent);
+begin
+  btwDemo.Refresh;
+end;
+
+end.
+

+ 40 - 0
demo/design/bulmatoast/index.html

@@ -0,0 +1,40 @@
+<!doctype html>
+<html lang="en">
+<head>
+  <meta http-equiv="Content-type" content="text/html; charset=utf-8">
+  <title>Bulma Toast demo</title>
+  <link href="bulma.min.css" rel="stylesheet">
+  <script  src="bulma-toast.min.js"></script>
+  <script  src="bulmatoast.js"></script>
+  <style>
+    #toast-parent {
+      position: fixed;
+      top: 20px;
+      z-index: 99;
+      width: 100%;
+    }
+  </style>
+</head>
+<body>
+  <div class="hero">
+    <div class="hero-body ">
+      <h2 class="title is-4">TBulmaToastWidget demo</h2>
+      <p class="subtitle">This is simple demo where a <em>TBulmaToastWidget</em> class is used to show a message toast
+      </p>
+    </div>
+  </div>
+  <hr class="my-4">
+  <div id="toast-parent" >
+  </div>
+  <div class="block">
+    <div class="is-flex is-justify-content-center">
+      <button id="btnShowToast" class="button is-primary">Show toast</button>
+    </div>
+  </div>
+
+  <script>
+    rtl.showUncaughtExceptions=true;
+    window.addEventListener("load", rtl.run);
+  </script>
+</body>
+</html>

+ 791 - 0
packages/bulma/bulmawidgets.pas

@@ -0,0 +1,791 @@
+unit bulmawidgets;
+
+{$mode objfpc}
+{$h+}
+{$modeswitch externalclass}
+
+Interface
+
+uses
+  Js,
+  web,
+  SysUtils,
+  Classes,
+  webwidget,
+  rtl.TemplateLoader;
+
+Const
+  DefaultClose = 'DefaultCloseClicks';
+
+Type
+
+  { TBulmaModal }
+  TOnModalHideEvent = Procedure (Sender : TObject; CloseEl : TJSHTMLElement; Values : TStrings) of object;
+
+  TModalItemKind = (mikValue,mikClose);
+
+  { TModalReferenceItem }
+
+  TModalReferenceItem = Class(TReferenceItem)
+  private
+    FInitialValue: String;
+    FKind: TModalItemKind;
+  Protected
+    Function GetValue: String;
+    Procedure SetValue(aValue: String);
+  Public
+    Procedure Assign(Source : TPersistent); override;
+    Property Value : String Read GetValue Write SetValue;
+  Published
+    Property Kind : TModalItemKind Read FKind Write FKind;
+    Property InitialValue : String Read FInitialValue Write FInitialValue;
+  end;
+
+  { TModalReferences }
+
+  TModalReferences = Class(TWebWidgetReferences)
+  private
+    function GetMR(aIndex : Integer): TModalReferenceItem;
+    procedure SetMR(aIndex : Integer; AValue: TModalReferenceItem);
+  Public
+    Function Add(Const aName : String; aSelector : String; aKind : TModalItemKind) : TModalReferenceItem; overload;
+    Property ModalRefs[aIndex : Integer] : TModalReferenceItem Read GetMR Write SetMR; default;
+  end;
+
+  TBulmaModal = Class(TCustomTemplateWidget)
+  private
+    FHideEl : TJSHTMLElement;
+    FBackDrop: Boolean;
+    FFocus: Boolean;
+    FKeyBoard: Boolean;
+    FOnHide: TOnModalHideEvent;
+    FShowOnRender: Boolean;
+    FTemplate: String;
+    FTemplateLoader: TCustomTemplateLoader;
+    FTemplateName: String;
+    FRemoveOnHide: Boolean;
+    FOKButtonName: String;
+    FCancelButtonName: String;
+    FCloseButtonName: String;
+    FOnRender: TNotifyEvent;
+    FOnShow: TNotifyEvent;
+    FShowing : Boolean;
+    procedure DoShow;
+    function GetModalReferences: TModalReferences;
+    procedure HideClick(Event: TJSEvent);
+    procedure SetModalReferences(AValue: TModalReferences);
+    procedure CheckRemove;
+    procedure SetTemplateLoader(AValue: TCustomTemplateLoader);
+  protected
+    function GetTemplateManager: TCustomTemplateLoader; virtual;
+    Function CreateReferences: TWebWidgetReferences; override;
+    Function ModalHide(Event : TJSEvent) : Boolean;
+    Function DoRenderHTML(aParent, aElement: TJSHTMLElement): TJSHTMLElement; override;
+    procedure Notification(AComponent: TComponent; Operation: TOperation); override;
+    Function GetTemplateHTML: String; override;
+    Procedure RefreshReferences; override;
+    procedure Loaded; override;
+    Function HTMLTag : String; override;
+  Public
+    Constructor Create(aOwner : TComponent); override;
+    Destructor Destroy; override;
+    procedure GetValues(aList: TStrings);
+    Procedure Show;
+    Procedure Hide;
+    Property Showing : Boolean Read FShowing;
+    // Id of the modal toplevel element. If not set, the first child is used.
+  Published
+    Property ParentID;
+    Property Styles;
+    Property StyleRefresh;
+    Property ElementID;
+    Property References : TModalReferences Read GetModalReferences Write SetModalReferences;
+    Property ShowOnRender: Boolean Read FShowOnRender Write FShowOnrender default False;
+    Property RemoveOnHide : Boolean Read FRemoveOnHide Write FRemoveOnHide default True;
+    Property BackDrop : Boolean Read FBackDrop Write FBackDrop default false;
+    Property KeyBoard : Boolean Read FKeyBoard Write FKeyBoard default false;
+    Property Focus : Boolean Read FFocus Write FFocus default false;
+    Property OKButtonName : String Read FOKButtonName write FOKButtonName;
+    Property CancelButtonName : String Read FCancelButtonName Write FCancelButtonName;
+    Property CloseButtonName : String Read FCloseButtonName Write FCloseButtonName;
+    // Template gets precedence over templatename;
+    Property Template : String Read FTemplate Write FTemplate;
+    Property TemplateName : String Read FTemplateName Write FTemplateName;
+    Property TemplateLoader : TCustomTemplateLoader Read FTemplateLoader Write SetTemplateLoader;
+    Property OnHide : TOnModalHideEvent Read FOnHide Write FOnHide;
+    Property OnRender : TNotifyEvent Read FOnRender Write FOnRender;
+    Property OnShow : TNotifyEvent Read FOnShow Write FOnShow;
+  end;
+
+  { TSimpleToastWidget }
+  TContextual = (cNone,
+                 cPrimary,cLink,cInfo,cSuccess,cWarning,cDanger,
+                 cWhite,cLight,cDark,cBlack,cText,cGhost);
+  TToastPosition = (tpDefault,
+               tpTopRight,tpTopLeft,tpTopCenter,
+               tpBottomRight,tpBottomLeft,tpBottomCenter,
+               tpCenter);
+
+  // Single toast message
+
+  TBaseBulmaToastWidget = Class(TCustomWebWidget)
+  private
+    FAnimate: Boolean;
+    FAutoHide: Boolean;
+    FBody: String;
+    FBoolean: Boolean;
+    FContextual: TContextual;
+    FHeader: String;
+    FHeaderImage: String;
+    FHideDelay: Integer;
+    FMinWidth: Integer;
+    FSingle: Boolean;
+    FPosition: TToastPosition;
+    procedure SetAnimate(AValue: Boolean);
+    procedure SetAutoHide(AValue: Boolean);
+    procedure SetBody(AValue: String);
+    procedure SetBoolean(AValue: Boolean);
+    procedure SetContextual(AValue: TContextual);
+    procedure SetHeader(AValue: String);
+    procedure SetHeaderImage(AValue: String);
+    procedure SetHideDelay(AValue: Integer);
+    procedure SetMinWidth(AValue: Integer);
+  Protected
+    FElement : TJSHTMLElement;
+    function BodyHTML: String; virtual;
+    function HeaderHTML: String; virtual;
+    Function DoRenderHTML(aParent, aElement: TJSHTMLElement): TJSHTMLElement;
+  Public
+    Constructor Create(aOwner : TComponent); override;
+    Procedure Refresh;
+    procedure Hide;
+  Protected
+    Property Header : String Read FHeader Write SetHeader;
+    Property Body : String Read FBody Write SetBody;
+    Property HeaderImage : String Read FHeaderImage Write SetHeaderImage;
+    Property CloseButton : Boolean Read FBoolean Write SetBoolean;
+    Property Contextual : TContextual Read FContextual write SetContextual;
+    Property HideDelay : Integer Read FHideDelay Write SetHideDelay default 2000;
+    Property AutoHide : Boolean Read FAutoHide Write SetAutoHide default True;
+    Property Animate : Boolean Read FAnimate Write SetAnimate default False;
+    Property MinWidth : Integer Read FMinWidth Write SetMinWidth default 200;
+    Property Single : Boolean Read FSingle Write FSingle;
+    Property Position : TToastPosition Read FPosition Write FPosition default tpTopRight;
+  end;
+  
+  TBulmaToastWidget = class(TBaseBulmaToastWidget)
+  Published
+    Property Styles;
+    Property StyleRefresh;
+    Property References;
+    Property ParentID;
+    Property ElementID;
+    Property Header;
+    Property Body;
+    Property HeaderImage;
+    Property CloseButton;
+    Property Contextual;
+    Property HideDelay;
+    Property AutoHide;
+    Property Animate;
+    Property MinWidth;
+    Property Single;
+    Property Position;
+  end;
+
+  // Encapsulates the global tag where the toasts are shown.
+
+  { TToastManager }
+
+  TToastManager = Class(TComponent)
+  Private
+    class var
+      _instance : TToastManager;
+      _ToastID : NativeInt;
+  Private
+    FAnimate: Boolean;
+    FAutoHide: Boolean;
+    FHideDelay: Integer;
+    FMinheight: Integer;
+    FMinWidth: Integer;
+    FMultiToast: Boolean;
+    FToastIcon: String;
+    FParentID: String;
+    FToastPosition: TToastPosition;
+    procedure SetMinHeight(AValue: Integer);
+    procedure SetMultiToast(AValue: Boolean);
+    procedure SetParentID(const Value: String);
+    class function CreateElement(aTag : String; aID: String = ''): TJSHTMLElement; static;
+  Public
+    Constructor Create(aOwner : TComponent); override;
+    class function Instance : TToastManager;
+    Class Function getToastID : String;
+    Procedure clear;
+    function ShowToast(const aHeader, aBody: String; aContext: TContextual=cNone; Closable: Boolean=True; aDelay : Integer = 0): TBaseBulmaToastWidget;
+  Published
+    Property ParentID : String Read FParentID Write SetParentID;
+    Property MultiToast : Boolean Read FMultiToast Write SetMultiToast;
+    Property MinHeight : Integer Read FMinheight Write SetMinHeight default 250;
+    Property ToastHideDelay : Integer Read FHideDelay Write FHideDelay default 2000;
+    Property ToastAutoHide : Boolean Read FAutoHide Write FAutoHide default True;
+    Property ToastAnimate : Boolean Read FAnimate Write FAnimate default False;
+    Property ToastMinWidth : Integer Read FMinWidth Write FMinWidth default 200;
+    Property ToastIcon : String Read FToastIcon Write FToastIcon;
+    Property ToastPosition : TToastPosition Read FToastPosition Write FToastPosition;
+  end;
+
+Const
+  ContextualNames : Array[TContextual] of string
+                  = ('','primary','link','info','success','warning','danger',
+                     'white','light','dark','black','text','ghost');
+  ToastPositionNames : Array[TToastPosition] of string =
+               ('top-right','top-right','top-left','top-center',
+                'bottom-right','bottom-left','bottom-center',
+                'center');
+
+Function Toasts : TToastManager;
+
+// Bulma-toast
+Type
+  TBulmaToast = Class {$IFDEF PAS2JS} external name 'bulmaToast' {$ENDIF} (TJSObject)
+  Public
+    class Procedure toast(aObject : TJSObject);
+    class Procedure setDoc(aEl : TJSObject);
+    class Procedure setDefaults(aObject : TJSObject);
+    class Procedure resetDefaults;
+  end;
+
+
+
+Implementation
+
+Resourcestring
+  SErrNoTemplateSet = '%s: No template set';
+//  SErrCannotUnrenderFixedElementID = 'Cannot unrender when ElementID (%s) is set';
+
+
+{ TModalReferenceItem }
+
+procedure TModalReferenceItem.Assign(Source: TPersistent);
+
+Var
+  MRI : TModalReferenceItem absolute Source;
+
+begin
+  if Source is TModalReferenceItem then
+    begin
+    Self.Kind:=MRI.Kind;
+    Self.InitialValue:=MRI.InitialValue;
+    end;
+  inherited Assign(Source);
+end;
+
+function TModalReferenceItem.GetValue: String;
+begin
+  if (Kind=mikValue) and (Element<>Nil) then
+    Result:=TJSHTMLInputElement(Element).value;
+end;
+
+procedure TModalReferenceItem.SetValue(aValue: String);
+begin
+  if (Kind=mikValue) and (Element<>Nil) then
+    TJSHTMLInputElement(Element).value:=aValue;
+end;
+
+{ TModalReferences }
+
+function TModalReferences.GetMR(aIndex : Integer): TModalReferenceItem;
+begin
+  Result:=TModalReferenceItem(Items[aIndex])
+end;
+
+procedure TModalReferences.SetMR(aIndex : Integer; AValue: TModalReferenceItem);
+begin
+  Items[aIndex]:=aValue;
+end;
+
+function TModalReferences.Add(const aName: String; aSelector: String; aKind: TModalItemKind): TModalReferenceItem;
+begin
+  Result:=TModalReferenceItem(Inherited Add(aName,aselector));
+  Result.Kind:=aKind;
+end;
+
+{ TBulmaModal }
+
+
+procedure TBulmaModal.Hide;
+
+begin
+  if Assigned(Element) then
+    Element.ClassList.remove('is-active');
+  FShowing:=False;
+end;
+
+procedure TBulmaModal.HideClick(Event: TJSEvent);
+
+begin
+  // Writeln('In hide click');
+  FHideEl:=TJSHtmlElement(Event.currentTarget);
+  ModalHide(Event);
+  Hide;
+end;
+
+procedure TBulmaModal.SetModalReferences(AValue: TModalReferences);
+begin
+  References.Assign(aValue);
+end;
+
+procedure TBulmaModal.Loaded;
+begin
+  inherited;
+end;
+
+function TBulmaModal.HTMLTag: String;
+begin
+  Result:='div'
+end;
+
+procedure TBulmaModal.GetValues(aList: TStrings);
+
+Var
+  I : integer;
+  Itm : TModalReferenceItem;
+
+begin
+  For I:=0 to references.Count-1 do
+    begin
+    Itm:=references[i];
+    if (itm.Kind=mikValue) and assigned(itm.Element) then
+      aList.Values[Itm.Name]:=Itm.Value
+    end;
+end;
+
+procedure TBulmaModal.CheckRemove;
+
+begin
+  if FRemoveOnHide then
+    UnRender;
+end;
+
+procedure TBulmaModal.SetTemplateLoader(AValue: TCustomTemplateLoader);
+begin
+  if FTemplateLoader=AValue then Exit;
+  if assigned(FTemplateLoader) then
+    FTemplateLoader.RemoveFreeNotification(Self);
+  FTemplateLoader:=AValue;
+  if assigned(FTemplateLoader) then
+    FTemplateLoader.FreeNotification(Self);
+end;
+
+function TBulmaModal.CreateReferences: TWebWidgetReferences;
+begin
+  Result:=TModalReferences.Create(Self,TModalReferenceItem);
+end;
+
+function TBulmaModal.ModalHide(Event: TJSEvent): Boolean;
+
+Var
+  L : Tstrings;
+
+begin
+  // Writeln('In bootstraphide callback ', assigned(onhide));
+  // Note that this can still be called after the bootstrap modal is destroyed.
+  Result:=False;
+  If Assigned(OnHide) then
+    begin
+    L:=TStringList.Create;
+    GetValues(L);
+    if L.Count=0 then
+      FreeAndNil(L);
+    Try
+      OnHide(Self,FHideEl,L);
+    finally
+      L.Free;
+    end;
+    end;
+  CheckRemove;
+  // Sometimes it gets stuck so we force remove it because it messes up the scrollbars...
+
+end;
+
+destructor TBulmaModal.Destroy;
+begin
+  CheckRemove;
+  inherited;
+end;
+
+function TBulmaModal.DoRenderHTML(aParent, aElement: TJSHTMLElement): TJSHTMLElement;
+
+begin
+  FHideEl:=Nil;
+  Result:=inherited DoRenderHTML(aParent, aElement);
+end;
+
+procedure TBulmaModal.Notification(AComponent: TComponent; Operation: TOperation
+  );
+begin
+  inherited Notification(AComponent, Operation);
+  if (Operation=opRemove) and (aComponent=TemplateLoader) then
+    FTemplateLoader:=Nil;
+end;
+
+
+function TBulmaModal.GetTemplateHTML: String;
+begin
+  Result:=FTemplate;
+  if Result='' then
+    if Assigned(TemplateLoader) then
+      Result:=TemplateLoader.Templates[TemplateName]
+    else
+      Result:=globalTemplates.Templates[TemplateName];
+end;
+
+procedure TBulmaModal.RefreshReferences;
+
+Var
+  I : Integer;
+  E : TJSHTMLElement;
+  MR : TModalReferenceItem;
+  NList : TJSNodeList;
+  N : TJSNode;
+begin
+  inherited RefreshReferences;
+  // Specials from Bulma itself
+  NList:=Element.querySelectorAll('.modal-background, .modal-close, .modal-card-head .delete');
+  for I:=0 to Nlist.length-1 do
+    TJSHTMLElement(NList.Nodes[i]).addEventListener('click',@HideClick);
+  E:=References.FindElementByName('OK');
+  if (E<>Nil) then
+    E.addEventListener('click',@HideClick);
+  for I:=0 to References.Count-1 do
+    begin
+    MR:=References[i];
+    if (MR.Kind=mikClose) then
+      begin
+      if MR.Exists then
+        if Not MR.IsArray then
+          MR.Element.AddEventListener('click',@HideClick)
+        else
+          For E in MR.Elements do
+            E.AddEventListener('click',@HideClick);
+        end
+    else if (MR.Kind=mikValue) then
+      begin
+      if (MR.element<>Nil) and (MR.InitialValue<>'') then
+        MR.Value:=MR.InitialValue;
+      end;
+    end;
+end;
+
+constructor TBulmaModal.Create(aOwner: TComponent);
+begin
+  inherited;
+  FRemoveOnHide:=True;
+end;
+
+function TBulmaModal.GetModalReferences: TModalReferences;
+begin
+  Result:=TModalReferences(Inherited References);
+end;
+
+
+procedure TBulmaModal.DoShow;
+
+begin
+  FHideEl:=Nil;
+  if not IsRendered then
+    Refresh;
+  Element.ClassList.Add('is-active');
+  FShowing:=True;
+  if Assigned(FOnShow) then
+    FOnShow(Self);
+end;
+
+Function TBulmaModal.GetTemplateManager : TCustomTemplateLoader;
+
+begin
+  if Assigned(TemplateLoader) then
+    Result:=TemplateLoader
+  else
+    Result:=GlobalTemplates;
+end;
+
+procedure TBulmaModal.Show;
+
+  procedure DoShowTemplate(Sender: TObject; const aTemplate: String);
+  begin
+    Template:=GetTemplateManager.Templates[aTemplate];
+    DoShow;
+  end;
+
+begin
+  if (Template<>'') or (ElementID<>'') Then
+    DoShow
+  else if TemplateName<>'' then
+    GetTemplateManager.IfTemplate(TemplateName,@DoShowTemplate)
+  else
+    Raise EWidgets.CreateFmt(SErrNoTemplateSet,[Name]);
+end;
+
+{ TBulmaToast }
+
+function Toasts: TToastManager;
+begin
+  Result:=TToastManager.Instance;
+end;
+
+{ TToastManager }
+
+class function TToastManager.Instance: TToastManager;
+begin
+  if _instance=Nil then
+   _instance:=TToastManager.Create(Nil);
+  Result:=_instance;
+end;
+
+
+procedure TToastManager.SetMinHeight(AValue: Integer);
+begin
+  if FMinheight=AValue then Exit;
+  FMinheight:=AValue;
+end;
+
+procedure TToastManager.SetMultiToast(AValue: Boolean);
+begin
+  if FMultiToast=AValue then Exit;
+  FMultiToast:=AValue;
+end;
+
+procedure TToastManager.SetParentID(const Value: String);
+begin
+  FParentID := Value;
+  if ParentID<>'' then
+    TBulmaToast.SetDoc(document.getElementById(ParentID));
+end;
+
+
+
+class function TToastManager.getToastID: String;
+begin
+  Inc(_ToastID);
+  Result:='toast-'+intToStr(_ToastID);
+end;
+
+Class Function TToastManager.CreateElement(aTag : String; aID : String = '') : TJSHTMLElement;
+
+begin
+  Result:=TJSHTMLElement(document.CreateElement(aTag));
+  if aID='' then
+    aID:=GetToastID;
+  Result.ID:=aID;
+end;
+
+
+procedure TToastManager.clear;
+begin
+  if (ParentID<>'') then
+    document.getElementById(ParentID).innerHTML:='';
+end;
+
+constructor TToastManager.Create(aOwner: TComponent);
+begin
+  inherited Create(aOwner);
+  FMinHeight:=250;
+  FMinWidth:=200;
+  FMultiToast:=True;
+  FHideDelay:=2000;
+  FAutoHide:=True;
+  FAnimate:=False;
+end;
+
+function TToastManager.ShowToast(const aHeader, aBody: String; aContext : TContextual = cNone; Closable: Boolean = True; aDelay : Integer = 0): TBaseBulmaToastWidget;
+
+Var
+  MsgDelay : Integer;
+  aHide : Boolean;
+
+begin
+  MsgDelay:=aDelay;
+  if MsgDelay=0 then
+    begin
+    MsgDelay:=ToastHideDelay;
+    aHide:=ToastAutoHide;
+    end
+  else if MsgDelay=-1 then
+    begin
+    MsgDelay:=0;
+    aHide:=False;
+    end;
+  Result:=TBaseBulmaToastWidget.Create(Self) ;
+  With Result do
+    begin
+    Header:=aHeader;
+    Body:=aBody;
+    HeaderImage:=ToastIcon;
+    CloseButton:=Closable;
+    Contextual:=aContext;
+    AutoHide:=aHide;
+    HideDelay:=MsgDelay;
+    Animate:=ToastAnimate;
+    MinWidth:=ToastMinWidth;
+    Single:=Not Multitoast;
+    if ToastPosition<>tpDefault then
+      Position:=ToastPosition;
+    Refresh;
+    end;
+end;
+
+{ TBaseBulmaToastWidget }
+
+
+procedure TBaseBulmaToastWidget.SetBody(AValue: String);
+begin
+  if FBody=AValue then Exit;
+  FBody:=AValue;
+  if isRendered then Refresh;
+end;
+
+procedure TBaseBulmaToastWidget.SetAnimate(AValue: Boolean);
+begin
+  if FAnimate=AValue then Exit;
+  FAnimate:=AValue;
+  if isRendered then Refresh;
+end;
+
+procedure TBaseBulmaToastWidget.SetAutoHide(AValue: Boolean);
+begin
+  if FAutoHide=AValue then Exit;
+  FAutoHide:=AValue;
+  if isRendered then Refresh;
+end;
+
+procedure TBaseBulmaToastWidget.SetBoolean(AValue: Boolean);
+begin
+  if FBoolean=AValue then Exit;
+  FBoolean:=AValue;
+  if isRendered then Refresh;
+end;
+
+procedure TBaseBulmaToastWidget.SetContextual(AValue: TContextual);
+begin
+  if FContextual=AValue then Exit;
+  FContextual:=AValue;
+  if isRendered then Refresh;
+end;
+
+procedure TBaseBulmaToastWidget.SetHeader(AValue: String);
+begin
+  if FHeader=AValue then Exit;
+  FHeader:=AValue;
+  if isRendered then Refresh;
+end;
+
+procedure TBaseBulmaToastWidget.SetHeaderImage(AValue: String);
+begin
+  if FHeaderImage=AValue then Exit;
+  FHeaderImage:=AValue;
+  if isRendered then Refresh;
+end;
+
+procedure TBaseBulmaToastWidget.SetHideDelay(AValue: Integer);
+begin
+  if FHideDelay=AValue then Exit;
+  FHideDelay:=AValue;
+  if isRendered then Refresh;
+end;
+
+procedure TBaseBulmaToastWidget.SetMinWidth(AValue: Integer);
+begin
+  if FMinWidth=AValue then Exit;
+  FMinWidth:=AValue;
+  if isRendered then Refresh;
+end;
+
+
+function TBaseBulmaToastWidget.HeaderHTML: String;
+
+Var
+  S : String;
+
+begin
+  Result:='';
+  if (Header='') and (HeaderImage='') then
+    exit;
+  S:=ContextualNames[Contextual];
+  if S<>'' then
+    S:=' is-'+S;
+  Result:='<p class="title is-6 is-small">';
+  if HeaderImage<>'' then
+    Result:=Result+'<img src="'+HeaderImage+'" class="icon is-small">';
+  Result:=Result+Header;
+  Result:=Result+'</p>'
+end;
+
+
+function TBaseBulmaToastWidget.BodyHTML: String;
+
+begin
+  Result:='<div class="message-body is-light">';
+  Result:=Result+HeaderHTML;
+  Result:=Result+'<p>'+Body+'</p>';
+  Result:=Result+'</div>';
+end;
+
+function TBaseBulmaToastWidget.DoRenderHTML(aParent, aElement: TJSHTMLElement): TJSHTMLElement;
+
+Var
+  S : String;
+Begin
+  S:=ContextualNames[Contextual];
+  if S<>'' then
+    S:='is-'+S;
+  Result:=aElement;
+  Result.ClassName:='message is-small is-light '+S;
+  Result.Style.CSSText:='min-width: '+IntToStr(MinWidth)+'px;';
+  Result.InnerHTML:={HeaderHTML+}BodyHTML;
+end;
+
+constructor TBaseBulmaToastWidget.Create(aOwner: TComponent);
+begin
+  inherited Create(aOwner);
+  FMinWidth:=200;
+  FAutoHide:=True;
+  FHideDelay:=2000;
+  FPosition:=tpTopRight;
+end;
+
+procedure TBaseBulmaToastWidget.Hide;
+begin
+
+end;
+
+
+procedure TBaseBulmaToastWidget.Refresh;
+Var
+  S : String;
+  Opts : TJSObject;
+  aDelay : NativeInt;
+
+Begin
+  S:=ContextualNames[Contextual];
+  if S<>'' then
+    S:='is-'+S;
+  FElement:=TToastManager.CreateElement('article');
+  aDelay:=FHideDelay;
+  if Not AutoHide then // we let it display for 1 day
+    aDelay:=24*3600*1000;
+  DoRenderHTML(Nil,FElement);
+  Opts:=New([
+    'message', FElement,
+    'type', S,
+    'single', single,
+    'animate',FAnimate,
+    'dismissible', CloseButton ,
+    'position',ToastPositionNames[Position],
+    'duration',aDelay,
+    'extraClasses','is-light'
+  ]);
+  TBulmaToast.toast(Opts);
+end;
+
+end.

Vissa filer visades inte eftersom för många filer har ändrats