html-flip-book-react 0.0.0-alpha.1 → 0.0.0-alpha.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/dist/FlipBook.d.ts +26 -0
  2. package/dist/FlipBook.d.ts.map +1 -0
  3. package/dist/assets/html-flip-book.css +1 -0
  4. package/dist/flip-book.js +47 -1405
  5. package/dist/flip-book.js.map +1 -1
  6. package/dist/toolbar/FirstPageButton.d.ts +9 -0
  7. package/dist/toolbar/FirstPageButton.d.ts.map +1 -0
  8. package/dist/toolbar/FullscreenButton.d.ts +11 -0
  9. package/dist/toolbar/FullscreenButton.d.ts.map +1 -0
  10. package/dist/toolbar/LastPageButton.d.ts +9 -0
  11. package/dist/toolbar/LastPageButton.d.ts.map +1 -0
  12. package/dist/toolbar/NextButton.d.ts +9 -0
  13. package/dist/toolbar/NextButton.d.ts.map +1 -0
  14. package/dist/toolbar/PageIndicator.d.ts +9 -0
  15. package/dist/toolbar/PageIndicator.d.ts.map +1 -0
  16. package/dist/toolbar/PrevButton.d.ts +9 -0
  17. package/dist/toolbar/PrevButton.d.ts.map +1 -0
  18. package/dist/toolbar/Toolbar.d.ts +13 -0
  19. package/dist/toolbar/Toolbar.d.ts.map +1 -0
  20. package/dist/toolbar/ToolbarButton.d.ts +13 -0
  21. package/dist/toolbar/ToolbarButton.d.ts.map +1 -0
  22. package/dist/toolbar/ToolbarContext.d.ts +15 -0
  23. package/dist/toolbar/ToolbarContext.d.ts.map +1 -0
  24. package/dist/toolbar/index.d.ts +19 -0
  25. package/dist/toolbar/index.d.ts.map +1 -0
  26. package/dist/toolbar/index.js +174 -0
  27. package/dist/toolbar/index.js.map +1 -0
  28. package/package.json +45 -43
  29. package/dist/flip-book.d.ts +0 -14
  30. package/dist/flip-book.d.ts.map +0 -1
  31. package/example/.vscode/settings.json +0 -3
  32. package/example/README.md +0 -47
  33. package/example/assets/pages_data/en/assets/cover.jpg +0 -0
  34. package/example/assets/pages_data/en/assets/sql-command.png +0 -0
  35. package/example/assets/pages_data/en/content/000-introduction.md +0 -85
  36. package/example/assets/pages_data/en/content/001-databases.md +0 -39
  37. package/example/assets/pages_data/en/content/002-install-mysql.md +0 -162
  38. package/example/assets/pages_data/en/content/003-creating-tables.md +0 -304
  39. package/example/assets/pages_data/en/content/004-basic-syntax.md +0 -145
  40. package/example/assets/pages_data/en/content/005-select.md +0 -359
  41. package/example/assets/pages_data/en/content/006-where.md +0 -225
  42. package/example/assets/pages_data/en/content/007-order-and-group-by.md +0 -142
  43. package/example/assets/pages_data/en/content/008-insert.md +0 -86
  44. package/example/assets/pages_data/en/content/009-update.md +0 -92
  45. package/example/assets/pages_data/en/content/010-delete.md +0 -28
  46. package/example/assets/pages_data/en/content/011-join.md +0 -297
  47. package/example/assets/pages_data/en/content/012-sql-command-categories.md +0 -121
  48. package/example/assets/pages_data/en/content/013-sub-queries.md +0 -112
  49. package/example/assets/pages_data/en/content/014-unions.md +0 -124
  50. package/example/assets/pages_data/en/content/015-Keys-in-a-Relational Database.md +0 -51
  51. package/example/assets/pages_data/en/content/016-Logical-operator-keywords.md +0 -17
  52. package/example/assets/pages_data/en/content/017-having-clause_aggregate-functions.md +0 -184
  53. package/example/assets/pages_data/en/content/018-essential-mysql-functions.md +0 -190
  54. package/example/assets/pages_data/en/content/019-triggers-in-sql.md +0 -133
  55. package/example/assets/pages_data/en/content/020-TCL-commands.md +0 -154
  56. package/example/assets/pages_data/en/content/021-DCL-commands.md +0 -126
  57. package/example/assets/pages_data/en/content/100-mysqldump.md +0 -109
  58. package/example/assets/pages_data/en/content/101-learn-materialize.md +0 -267
  59. package/example/assets/pages_data/en/content/999-conclusion.md +0 -24
  60. package/example/assets/pages_data/he/4.txt +0 -2
  61. package/example/assets/pages_data/he/5.txt +0 -4
  62. package/example/assets/pages_data/he/6.txt +0 -4
  63. package/example/index.html +0 -21
  64. package/example/package-lock.json +0 -5324
  65. package/example/package.json +0 -39
  66. package/example/src/App.css +0 -52
  67. package/example/src/App.tsx +0 -25
  68. package/example/src/EnBook.tsx +0 -55
  69. package/example/src/HeBook.tsx +0 -44
  70. package/example/src/index.tsx +0 -12
  71. package/example/vite-env.d.ts +0 -1
  72. package/example/vite.config.js +0 -84
  73. package/src/FlipBook.tsx +0 -45
  74. package/vite.config.js +0 -66
@@ -0,0 +1,174 @@
1
+ import { jsx as n } from "react/jsx-runtime";
2
+ import { createContext as v, useContext as x, useState as i, useCallback as P, useEffect as k } from "react";
3
+ const u = ({
4
+ onClick: e,
5
+ ariaLabel: t,
6
+ disabled: l = !1,
7
+ children: r,
8
+ className: a = "",
9
+ title: o
10
+ }) => /* @__PURE__ */ n(
11
+ "button",
12
+ {
13
+ type: "button",
14
+ onClick: e,
15
+ "aria-label": t,
16
+ disabled: l,
17
+ title: o ?? t,
18
+ className: `flipbook-toolbar-button ${a}`.trim(),
19
+ children: r
20
+ }
21
+ ), h = v(null);
22
+ function b() {
23
+ const e = x(h);
24
+ if (!e)
25
+ throw new Error("Toolbar components must be used within a Toolbar");
26
+ return e;
27
+ }
28
+ const N = ({ children: e, className: t }) => {
29
+ const { flipBookRef: l, isFirstPage: r } = b();
30
+ return /* @__PURE__ */ n(
31
+ u,
32
+ {
33
+ onClick: () => {
34
+ l.current?.jumpToPage(0);
35
+ },
36
+ ariaLabel: "First page",
37
+ disabled: r,
38
+ className: `flipbook-toolbar-first ${t ?? ""}`.trim(),
39
+ children: e ?? "⏮"
40
+ }
41
+ );
42
+ }, T = ({
43
+ targetRef: e,
44
+ enterIcon: t,
45
+ exitIcon: l,
46
+ className: r
47
+ }) => {
48
+ const [a, o] = i(!1), s = P(() => {
49
+ o(!!document.fullscreenElement);
50
+ }, []);
51
+ k(() => (document.addEventListener("fullscreenchange", s), () => {
52
+ document.removeEventListener("fullscreenchange", s);
53
+ }), [s]);
54
+ const g = async () => {
55
+ try {
56
+ a ? await document.exitFullscreen() : await (e?.current ?? document.documentElement).requestFullscreen();
57
+ } catch (d) {
58
+ console.warn("Fullscreen request failed:", d);
59
+ }
60
+ }, f = a ? "Exit fullscreen" : "Enter fullscreen", p = a ? l ?? "⛶" : t ?? "⛶";
61
+ return /* @__PURE__ */ n(
62
+ u,
63
+ {
64
+ onClick: g,
65
+ ariaLabel: f,
66
+ className: `flipbook-toolbar-fullscreen ${a ? "flipbook-toolbar-fullscreen--active" : ""} ${r ?? ""}`.trim(),
67
+ children: p
68
+ }
69
+ );
70
+ }, $ = ({ children: e, className: t }) => {
71
+ const { flipBookRef: l, isLastPage: r, totalPages: a } = b();
72
+ return /* @__PURE__ */ n(
73
+ u,
74
+ {
75
+ onClick: () => {
76
+ l.current?.jumpToPage(a - 1);
77
+ },
78
+ ariaLabel: "Last page",
79
+ disabled: r,
80
+ className: `flipbook-toolbar-last ${t ?? ""}`.trim(),
81
+ children: e ?? "⏭"
82
+ }
83
+ );
84
+ }, B = ({ children: e, className: t }) => {
85
+ const { flipBookRef: l, isLastPage: r, direction: a } = b();
86
+ return /* @__PURE__ */ n(
87
+ u,
88
+ {
89
+ onClick: () => {
90
+ l.current?.flipNext();
91
+ },
92
+ ariaLabel: a === "rtl" ? "Previous page" : "Next page",
93
+ disabled: r,
94
+ className: `flipbook-toolbar-next ${t ?? ""}`.trim(),
95
+ children: e ?? "›"
96
+ }
97
+ );
98
+ }, E = ({
99
+ format: e = "{current} / {total}",
100
+ className: t
101
+ }) => {
102
+ const { currentPage: l, totalPages: r } = b(), a = l + 1, o = e.replace("{current}", a.toString()).replace("{total}", r.toString());
103
+ return /* @__PURE__ */ n(
104
+ "span",
105
+ {
106
+ className: `flipbook-toolbar-indicator ${t ?? ""}`.trim(),
107
+ "aria-live": "polite",
108
+ "aria-atomic": "true",
109
+ children: o
110
+ }
111
+ );
112
+ }, I = ({ children: e, className: t }) => {
113
+ const { flipBookRef: l, isFirstPage: r, direction: a } = b();
114
+ return /* @__PURE__ */ n(
115
+ u,
116
+ {
117
+ onClick: () => {
118
+ l.current?.flipPrev();
119
+ },
120
+ ariaLabel: a === "rtl" ? "Next page" : "Previous page",
121
+ disabled: r,
122
+ className: `flipbook-toolbar-prev ${t ?? ""}`.trim(),
123
+ children: e ?? "‹"
124
+ }
125
+ );
126
+ }, w = ({
127
+ flipBookRef: e,
128
+ direction: t = "ltr",
129
+ className: l = "",
130
+ children: r
131
+ }) => {
132
+ const [a, o] = i(0), [s, g] = i(0), [f, p] = i(!0), [d, C] = i(!1), m = P(() => {
133
+ const c = e.current;
134
+ c && (o(c.getCurrentPageIndex()), g(c.getTotalPages()), p(c.isFirstPage()), C(c.isLastPage()));
135
+ }, [e]);
136
+ return k(() => {
137
+ m();
138
+ const c = setInterval(m, 100);
139
+ return () => clearInterval(c);
140
+ }, [m]), /* @__PURE__ */ n(
141
+ h.Provider,
142
+ {
143
+ value: {
144
+ flipBookRef: e,
145
+ direction: t,
146
+ currentPage: a,
147
+ totalPages: s,
148
+ isFirstPage: f,
149
+ isLastPage: d
150
+ },
151
+ children: /* @__PURE__ */ n(
152
+ "div",
153
+ {
154
+ className: `flipbook-toolbar ${t === "rtl" ? "flipbook-toolbar--rtl" : ""} ${l}`.trim(),
155
+ role: "toolbar",
156
+ "aria-label": "FlipBook navigation",
157
+ children: r
158
+ }
159
+ )
160
+ }
161
+ );
162
+ };
163
+ export {
164
+ N as FirstPageButton,
165
+ T as FullscreenButton,
166
+ $ as LastPageButton,
167
+ B as NextButton,
168
+ E as PageIndicator,
169
+ I as PrevButton,
170
+ w as Toolbar,
171
+ u as ToolbarButton,
172
+ b as useToolbar
173
+ };
174
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../../src/toolbar/ToolbarButton.tsx","../../src/toolbar/ToolbarContext.tsx","../../src/toolbar/FirstPageButton.tsx","../../src/toolbar/FullscreenButton.tsx","../../src/toolbar/LastPageButton.tsx","../../src/toolbar/NextButton.tsx","../../src/toolbar/PageIndicator.tsx","../../src/toolbar/PrevButton.tsx","../../src/toolbar/Toolbar.tsx"],"sourcesContent":["import type React from \"react\";\n\ninterface ToolbarButtonProps {\n\t/** Click handler */\n\tonClick: () => void;\n\t/** Accessible label for the button */\n\tariaLabel: string;\n\t/** Whether the button is disabled */\n\tdisabled?: boolean;\n\t/** Button content (icon or text) */\n\tchildren: React.ReactNode;\n\t/** Additional CSS class name */\n\tclassName?: string;\n\t/** Title tooltip */\n\ttitle?: string;\n}\n\n/**\n * Base button component for toolbar actions.\n */\nconst ToolbarButton: React.FC<ToolbarButtonProps> = ({\n\tonClick,\n\tariaLabel,\n\tdisabled = false,\n\tchildren,\n\tclassName = \"\",\n\ttitle,\n}) => {\n\treturn (\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tonClick={onClick}\n\t\t\taria-label={ariaLabel}\n\t\t\tdisabled={disabled}\n\t\t\ttitle={title ?? ariaLabel}\n\t\t\tclassName={`flipbook-toolbar-button ${className}`.trim()}\n\t\t>\n\t\t\t{children}\n\t\t</button>\n\t);\n};\n\nexport { ToolbarButton };\nexport type { ToolbarButtonProps };\n","import type React from \"react\";\nimport { createContext, useContext } from \"react\";\nimport type { FlipBookHandle } from \"../FlipBook\";\n\ninterface ToolbarContextValue {\n\tflipBookRef: React.RefObject<FlipBookHandle | null>;\n\tdirection: \"ltr\" | \"rtl\";\n\tcurrentPage: number;\n\ttotalPages: number;\n\tisFirstPage: boolean;\n\tisLastPage: boolean;\n}\n\nconst ToolbarContext = createContext<ToolbarContextValue | null>(null);\n\nexport function useToolbar(): ToolbarContextValue {\n\tconst context = useContext(ToolbarContext);\n\tif (!context) {\n\t\tthrow new Error(\"Toolbar components must be used within a Toolbar\");\n\t}\n\treturn context;\n}\n\nexport { ToolbarContext };\nexport type { ToolbarContextValue };\n","import type React from \"react\";\nimport { ToolbarButton } from \"./ToolbarButton\";\nimport { useToolbar } from \"./ToolbarContext\";\n\ninterface FirstPageButtonProps {\n\t/** Custom content (icon or text). Defaults to \"⏮\" */\n\tchildren?: React.ReactNode;\n\t/** Additional CSS class name */\n\tclassName?: string;\n}\n\n/**\n * Button to navigate to the first page.\n */\nconst FirstPageButton: React.FC<FirstPageButtonProps> = ({ children, className }) => {\n\tconst { flipBookRef, isFirstPage } = useToolbar();\n\n\tconst handleClick = () => {\n\t\tflipBookRef.current?.jumpToPage(0);\n\t};\n\n\treturn (\n\t\t<ToolbarButton\n\t\t\tonClick={handleClick}\n\t\t\tariaLabel=\"First page\"\n\t\t\tdisabled={isFirstPage}\n\t\t\tclassName={`flipbook-toolbar-first ${className ?? \"\"}`.trim()}\n\t\t>\n\t\t\t{children ?? \"⏮\"}\n\t\t</ToolbarButton>\n\t);\n};\n\nexport { FirstPageButton };\nexport type { FirstPageButtonProps };\n","import type React from \"react\";\nimport { useCallback, useEffect, useState } from \"react\";\nimport { ToolbarButton } from \"./ToolbarButton\";\n\ninterface FullscreenButtonProps {\n\t/** Target element to make fullscreen. If not provided, uses document.documentElement */\n\ttargetRef?: React.RefObject<HTMLElement | null>;\n\t/** Custom content for enter fullscreen. Defaults to \"⛶\" */\n\tenterIcon?: React.ReactNode;\n\t/** Custom content for exit fullscreen. Defaults to \"⛶\" */\n\texitIcon?: React.ReactNode;\n\t/** Additional CSS class name */\n\tclassName?: string;\n}\n\n/**\n * Button to toggle fullscreen mode.\n */\nconst FullscreenButton: React.FC<FullscreenButtonProps> = ({\n\ttargetRef,\n\tenterIcon,\n\texitIcon,\n\tclassName,\n}) => {\n\tconst [isFullscreen, setIsFullscreen] = useState(false);\n\n\t// Check fullscreen state\n\tconst updateFullscreenState = useCallback(() => {\n\t\tsetIsFullscreen(!!document.fullscreenElement);\n\t}, []);\n\n\tuseEffect(() => {\n\t\tdocument.addEventListener(\"fullscreenchange\", updateFullscreenState);\n\t\treturn () => {\n\t\t\tdocument.removeEventListener(\"fullscreenchange\", updateFullscreenState);\n\t\t};\n\t}, [updateFullscreenState]);\n\n\tconst handleClick = async () => {\n\t\ttry {\n\t\t\tif (isFullscreen) {\n\t\t\t\tawait document.exitFullscreen();\n\t\t\t} else {\n\t\t\t\tconst target = targetRef?.current ?? document.documentElement;\n\t\t\t\tawait target.requestFullscreen();\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconsole.warn(\"Fullscreen request failed:\", error);\n\t\t}\n\t};\n\n\tconst label = isFullscreen ? \"Exit fullscreen\" : \"Enter fullscreen\";\n\tconst icon = isFullscreen ? (exitIcon ?? \"⛶\") : (enterIcon ?? \"⛶\");\n\n\treturn (\n\t\t<ToolbarButton\n\t\t\tonClick={handleClick}\n\t\t\tariaLabel={label}\n\t\t\tclassName={`flipbook-toolbar-fullscreen ${isFullscreen ? \"flipbook-toolbar-fullscreen--active\" : \"\"} ${className ?? \"\"}`.trim()}\n\t\t>\n\t\t\t{icon}\n\t\t</ToolbarButton>\n\t);\n};\n\nexport { FullscreenButton };\nexport type { FullscreenButtonProps };\n","import type React from \"react\";\nimport { ToolbarButton } from \"./ToolbarButton\";\nimport { useToolbar } from \"./ToolbarContext\";\n\ninterface LastPageButtonProps {\n\t/** Custom content (icon or text). Defaults to \"⏭\" */\n\tchildren?: React.ReactNode;\n\t/** Additional CSS class name */\n\tclassName?: string;\n}\n\n/**\n * Button to navigate to the last page.\n */\nconst LastPageButton: React.FC<LastPageButtonProps> = ({ children, className }) => {\n\tconst { flipBookRef, isLastPage, totalPages } = useToolbar();\n\n\tconst handleClick = () => {\n\t\tflipBookRef.current?.jumpToPage(totalPages - 1);\n\t};\n\n\treturn (\n\t\t<ToolbarButton\n\t\t\tonClick={handleClick}\n\t\t\tariaLabel=\"Last page\"\n\t\t\tdisabled={isLastPage}\n\t\t\tclassName={`flipbook-toolbar-last ${className ?? \"\"}`.trim()}\n\t\t>\n\t\t\t{children ?? \"⏭\"}\n\t\t</ToolbarButton>\n\t);\n};\n\nexport { LastPageButton };\nexport type { LastPageButtonProps };\n","import type React from \"react\";\nimport { ToolbarButton } from \"./ToolbarButton\";\nimport { useToolbar } from \"./ToolbarContext\";\n\ninterface NextButtonProps {\n\t/** Custom content (icon or text). Defaults to \"›\" */\n\tchildren?: React.ReactNode;\n\t/** Additional CSS class name */\n\tclassName?: string;\n}\n\n/**\n * Button to navigate to the next page.\n */\nconst NextButton: React.FC<NextButtonProps> = ({ children, className }) => {\n\tconst { flipBookRef, isLastPage, direction } = useToolbar();\n\n\tconst handleClick = () => {\n\t\tflipBookRef.current?.flipNext();\n\t};\n\n\t// In RTL, the visual \"next\" is actually previous in reading order\n\tconst label = direction === \"rtl\" ? \"Previous page\" : \"Next page\";\n\n\treturn (\n\t\t<ToolbarButton\n\t\t\tonClick={handleClick}\n\t\t\tariaLabel={label}\n\t\t\tdisabled={isLastPage}\n\t\t\tclassName={`flipbook-toolbar-next ${className ?? \"\"}`.trim()}\n\t\t>\n\t\t\t{children ?? \"›\"}\n\t\t</ToolbarButton>\n\t);\n};\n\nexport { NextButton };\nexport type { NextButtonProps };\n","import type React from \"react\";\nimport { useToolbar } from \"./ToolbarContext\";\n\ninterface PageIndicatorProps {\n\t/** Format string with {current} and {total} placeholders. Defaults to \"{current} / {total}\" */\n\tformat?: string;\n\t/** Additional CSS class name */\n\tclassName?: string;\n}\n\n/**\n * Displays the current page position (e.g., \"3 / 10\").\n */\nconst PageIndicator: React.FC<PageIndicatorProps> = ({\n\tformat = \"{current} / {total}\",\n\tclassName,\n}) => {\n\tconst { currentPage, totalPages } = useToolbar();\n\n\t// Display 1-based page numbers for users\n\tconst displayPage = currentPage + 1;\n\n\tconst text = format\n\t\t.replace(\"{current}\", displayPage.toString())\n\t\t.replace(\"{total}\", totalPages.toString());\n\n\treturn (\n\t\t<span\n\t\t\tclassName={`flipbook-toolbar-indicator ${className ?? \"\"}`.trim()}\n\t\t\taria-live=\"polite\"\n\t\t\taria-atomic=\"true\"\n\t\t>\n\t\t\t{text}\n\t\t</span>\n\t);\n};\n\nexport { PageIndicator };\nexport type { PageIndicatorProps };\n","import type React from \"react\";\nimport { ToolbarButton } from \"./ToolbarButton\";\nimport { useToolbar } from \"./ToolbarContext\";\n\ninterface PrevButtonProps {\n\t/** Custom content (icon or text). Defaults to \"‹\" */\n\tchildren?: React.ReactNode;\n\t/** Additional CSS class name */\n\tclassName?: string;\n}\n\n/**\n * Button to navigate to the previous page.\n */\nconst PrevButton: React.FC<PrevButtonProps> = ({ children, className }) => {\n\tconst { flipBookRef, isFirstPage, direction } = useToolbar();\n\n\tconst handleClick = () => {\n\t\tflipBookRef.current?.flipPrev();\n\t};\n\n\t// In RTL, the visual \"previous\" is actually next in reading order\n\tconst label = direction === \"rtl\" ? \"Next page\" : \"Previous page\";\n\n\treturn (\n\t\t<ToolbarButton\n\t\t\tonClick={handleClick}\n\t\t\tariaLabel={label}\n\t\t\tdisabled={isFirstPage}\n\t\t\tclassName={`flipbook-toolbar-prev ${className ?? \"\"}`.trim()}\n\t\t>\n\t\t\t{children ?? \"‹\"}\n\t\t</ToolbarButton>\n\t);\n};\n\nexport { PrevButton };\nexport type { PrevButtonProps };\n","import type React from \"react\";\nimport { useCallback, useEffect, useState } from \"react\";\nimport type { FlipBookHandle } from \"../FlipBook\";\nimport { ToolbarContext } from \"./ToolbarContext\";\nimport \"./Toolbar.css\";\n\ninterface ToolbarProps {\n\t/** Ref to the FlipBook component for programmatic control */\n\tflipBookRef: React.RefObject<FlipBookHandle | null>;\n\t/** Text direction for button layout. Defaults to \"ltr\" */\n\tdirection?: \"ltr\" | \"rtl\";\n\t/** Additional CSS class name */\n\tclassName?: string;\n\t/** Toolbar children (buttons, indicators, etc.) */\n\tchildren: React.ReactNode;\n}\n\n/**\n * Container component for FlipBook toolbar controls.\n * Provides context to child components for accessing FlipBook methods.\n */\nconst Toolbar: React.FC<ToolbarProps> = ({\n\tflipBookRef,\n\tdirection = \"ltr\",\n\tclassName = \"\",\n\tchildren,\n}) => {\n\tconst [currentPage, setCurrentPage] = useState(0);\n\tconst [totalPages, setTotalPages] = useState(0);\n\tconst [isFirstPage, setIsFirstPage] = useState(true);\n\tconst [isLastPage, setIsLastPage] = useState(false);\n\n\t// Update state from FlipBook ref\n\tconst updateState = useCallback(() => {\n\t\tconst fb = flipBookRef.current;\n\t\tif (fb) {\n\t\t\tsetCurrentPage(fb.getCurrentPageIndex());\n\t\t\tsetTotalPages(fb.getTotalPages());\n\t\t\tsetIsFirstPage(fb.isFirstPage());\n\t\t\tsetIsLastPage(fb.isLastPage());\n\t\t}\n\t}, [flipBookRef]);\n\n\t// Initial state update and periodic polling\n\t// TODO: Replace with event-based updates when FlipBook emits page change events\n\tuseEffect(() => {\n\t\tupdateState();\n\t\tconst interval = setInterval(updateState, 100);\n\t\treturn () => clearInterval(interval);\n\t}, [updateState]);\n\n\treturn (\n\t\t<ToolbarContext.Provider\n\t\t\tvalue={{\n\t\t\t\tflipBookRef,\n\t\t\t\tdirection,\n\t\t\t\tcurrentPage,\n\t\t\t\ttotalPages,\n\t\t\t\tisFirstPage,\n\t\t\t\tisLastPage,\n\t\t\t}}\n\t\t>\n\t\t\t<div\n\t\t\t\tclassName={`flipbook-toolbar ${direction === \"rtl\" ? \"flipbook-toolbar--rtl\" : \"\"} ${className}`.trim()}\n\t\t\t\trole=\"toolbar\"\n\t\t\t\taria-label=\"FlipBook navigation\"\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t</div>\n\t\t</ToolbarContext.Provider>\n\t);\n};\n\nexport { Toolbar };\nexport type { ToolbarProps };\n"],"names":["ToolbarButton","onClick","ariaLabel","disabled","children","className","title","jsx","ToolbarContext","createContext","useToolbar","context","useContext","FirstPageButton","flipBookRef","isFirstPage","FullscreenButton","targetRef","enterIcon","exitIcon","isFullscreen","setIsFullscreen","useState","updateFullscreenState","useCallback","useEffect","handleClick","error","label","icon","LastPageButton","isLastPage","totalPages","NextButton","direction","PageIndicator","format","currentPage","displayPage","text","PrevButton","Toolbar","setCurrentPage","setTotalPages","setIsFirstPage","setIsLastPage","updateState","fb","interval"],"mappings":";;AAoBA,MAAMA,IAA8C,CAAC;AAAA,EACpD,SAAAC;AAAA,EACA,WAAAC;AAAA,EACA,UAAAC,IAAW;AAAA,EACX,UAAAC;AAAA,EACA,WAAAC,IAAY;AAAA,EACZ,OAAAC;AACD,MAEE,gBAAAC;AAAA,EAAC;AAAA,EAAA;AAAA,IACA,MAAK;AAAA,IACL,SAAAN;AAAA,IACA,cAAYC;AAAA,IACZ,UAAAC;AAAA,IACA,OAAOG,KAASJ;AAAA,IAChB,WAAW,2BAA2BG,CAAS,GAAG,KAAA;AAAA,IAEjD,UAAAD;AAAA,EAAA;AAAA,GCxBEI,IAAiBC,EAA0C,IAAI;AAE9D,SAASC,IAAkC;AACjD,QAAMC,IAAUC,EAAWJ,CAAc;AACzC,MAAI,CAACG;AACJ,UAAM,IAAI,MAAM,kDAAkD;AAEnE,SAAOA;AACR;ACPA,MAAME,IAAkD,CAAC,EAAE,UAAAT,GAAU,WAAAC,QAAgB;AACpF,QAAM,EAAE,aAAAS,GAAa,aAAAC,EAAA,IAAgBL,EAAA;AAMrC,SACC,gBAAAH;AAAA,IAACP;AAAA,IAAA;AAAA,MACA,SANkB,MAAM;AACzB,QAAAc,EAAY,SAAS,WAAW,CAAC;AAAA,MAClC;AAAA,MAKE,WAAU;AAAA,MACV,UAAUC;AAAA,MACV,WAAW,0BAA0BV,KAAa,EAAE,GAAG,KAAA;AAAA,MAEtD,UAAAD,KAAY;AAAA,IAAA;AAAA,EAAA;AAGhB,GCbMY,IAAoD,CAAC;AAAA,EAC1D,WAAAC;AAAA,EACA,WAAAC;AAAA,EACA,UAAAC;AAAA,EACA,WAAAd;AACD,MAAM;AACL,QAAM,CAACe,GAAcC,CAAe,IAAIC,EAAS,EAAK,GAGhDC,IAAwBC,EAAY,MAAM;AAC/C,IAAAH,EAAgB,CAAC,CAAC,SAAS,iBAAiB;AAAA,EAC7C,GAAG,CAAA,CAAE;AAEL,EAAAI,EAAU,OACT,SAAS,iBAAiB,oBAAoBF,CAAqB,GAC5D,MAAM;AACZ,aAAS,oBAAoB,oBAAoBA,CAAqB;AAAA,EACvE,IACE,CAACA,CAAqB,CAAC;AAE1B,QAAMG,IAAc,YAAY;AAC/B,QAAI;AACH,MAAIN,IACH,MAAM,SAAS,eAAA,IAGf,OADeH,GAAW,WAAW,SAAS,iBACjC,kBAAA;AAAA,IAEf,SAASU,GAAO;AACf,cAAQ,KAAK,8BAA8BA,CAAK;AAAA,IACjD;AAAA,EACD,GAEMC,IAAQR,IAAe,oBAAoB,oBAC3CS,IAAOT,IAAgBD,KAAY,MAAQD,KAAa;AAE9D,SACC,gBAAAX;AAAA,IAACP;AAAA,IAAA;AAAA,MACA,SAAS0B;AAAA,MACT,WAAWE;AAAA,MACX,WAAW,+BAA+BR,IAAe,wCAAwC,EAAE,IAAIf,KAAa,EAAE,GAAG,KAAA;AAAA,MAExH,UAAAwB;AAAA,IAAA;AAAA,EAAA;AAGJ,GCjDMC,IAAgD,CAAC,EAAE,UAAA1B,GAAU,WAAAC,QAAgB;AAClF,QAAM,EAAE,aAAAS,GAAa,YAAAiB,GAAY,YAAAC,EAAA,IAAetB,EAAA;AAMhD,SACC,gBAAAH;AAAA,IAACP;AAAA,IAAA;AAAA,MACA,SANkB,MAAM;AACzB,QAAAc,EAAY,SAAS,WAAWkB,IAAa,CAAC;AAAA,MAC/C;AAAA,MAKE,WAAU;AAAA,MACV,UAAUD;AAAA,MACV,WAAW,yBAAyB1B,KAAa,EAAE,GAAG,KAAA;AAAA,MAErD,UAAAD,KAAY;AAAA,IAAA;AAAA,EAAA;AAGhB,GCjBM6B,IAAwC,CAAC,EAAE,UAAA7B,GAAU,WAAAC,QAAgB;AAC1E,QAAM,EAAE,aAAAS,GAAa,YAAAiB,GAAY,WAAAG,EAAA,IAAcxB,EAAA;AAS/C,SACC,gBAAAH;AAAA,IAACP;AAAA,IAAA;AAAA,MACA,SATkB,MAAM;AACzB,QAAAc,EAAY,SAAS,SAAA;AAAA,MACtB;AAAA,MAQE,WALYoB,MAAc,QAAQ,kBAAkB;AAAA,MAMpD,UAAUH;AAAA,MACV,WAAW,yBAAyB1B,KAAa,EAAE,GAAG,KAAA;AAAA,MAErD,UAAAD,KAAY;AAAA,IAAA;AAAA,EAAA;AAGhB,GCrBM+B,IAA8C,CAAC;AAAA,EACpD,QAAAC,IAAS;AAAA,EACT,WAAA/B;AACD,MAAM;AACL,QAAM,EAAE,aAAAgC,GAAa,YAAAL,EAAA,IAAetB,EAAA,GAG9B4B,IAAcD,IAAc,GAE5BE,IAAOH,EACX,QAAQ,aAAaE,EAAY,SAAA,CAAU,EAC3C,QAAQ,WAAWN,EAAW,SAAA,CAAU;AAE1C,SACC,gBAAAzB;AAAA,IAAC;AAAA,IAAA;AAAA,MACA,WAAW,8BAA8BF,KAAa,EAAE,GAAG,KAAA;AAAA,MAC3D,aAAU;AAAA,MACV,eAAY;AAAA,MAEX,UAAAkC;AAAA,IAAA;AAAA,EAAA;AAGJ,GCrBMC,IAAwC,CAAC,EAAE,UAAApC,GAAU,WAAAC,QAAgB;AAC1E,QAAM,EAAE,aAAAS,GAAa,aAAAC,GAAa,WAAAmB,EAAA,IAAcxB,EAAA;AAShD,SACC,gBAAAH;AAAA,IAACP;AAAA,IAAA;AAAA,MACA,SATkB,MAAM;AACzB,QAAAc,EAAY,SAAS,SAAA;AAAA,MACtB;AAAA,MAQE,WALYoB,MAAc,QAAQ,cAAc;AAAA,MAMhD,UAAUnB;AAAA,MACV,WAAW,yBAAyBV,KAAa,EAAE,GAAG,KAAA;AAAA,MAErD,UAAAD,KAAY;AAAA,IAAA;AAAA,EAAA;AAGhB,GCbMqC,IAAkC,CAAC;AAAA,EACxC,aAAA3B;AAAA,EACA,WAAAoB,IAAY;AAAA,EACZ,WAAA7B,IAAY;AAAA,EACZ,UAAAD;AACD,MAAM;AACL,QAAM,CAACiC,GAAaK,CAAc,IAAIpB,EAAS,CAAC,GAC1C,CAACU,GAAYW,CAAa,IAAIrB,EAAS,CAAC,GACxC,CAACP,GAAa6B,CAAc,IAAItB,EAAS,EAAI,GAC7C,CAACS,GAAYc,CAAa,IAAIvB,EAAS,EAAK,GAG5CwB,IAActB,EAAY,MAAM;AACrC,UAAMuB,IAAKjC,EAAY;AACvB,IAAIiC,MACHL,EAAeK,EAAG,qBAAqB,GACvCJ,EAAcI,EAAG,eAAe,GAChCH,EAAeG,EAAG,aAAa,GAC/BF,EAAcE,EAAG,YAAY;AAAA,EAE/B,GAAG,CAACjC,CAAW,CAAC;AAIhB,SAAAW,EAAU,MAAM;AACf,IAAAqB,EAAA;AACA,UAAME,IAAW,YAAYF,GAAa,GAAG;AAC7C,WAAO,MAAM,cAAcE,CAAQ;AAAA,EACpC,GAAG,CAACF,CAAW,CAAC,GAGf,gBAAAvC;AAAA,IAACC,EAAe;AAAA,IAAf;AAAA,MACA,OAAO;AAAA,QACN,aAAAM;AAAA,QACA,WAAAoB;AAAA,QACA,aAAAG;AAAA,QACA,YAAAL;AAAA,QACA,aAAAjB;AAAA,QACA,YAAAgB;AAAA,MAAA;AAAA,MAGD,UAAA,gBAAAxB;AAAA,QAAC;AAAA,QAAA;AAAA,UACA,WAAW,oBAAoB2B,MAAc,QAAQ,0BAA0B,EAAE,IAAI7B,CAAS,GAAG,KAAA;AAAA,UACjG,MAAK;AAAA,UACL,cAAW;AAAA,UAEV,UAAAD;AAAA,QAAA;AAAA,MAAA;AAAA,IACF;AAAA,EAAA;AAGH;"}
package/package.json CHANGED
@@ -1,45 +1,47 @@
1
1
  {
2
- "name": "html-flip-book-react",
3
- "description": "Flip Book React Component",
4
- "version": "0.0.0-alpha.1",
5
- "type": "module",
6
- "author": "DoradSoft",
7
- "main": "./dist/flip-book.js",
8
- "types": "./dist/flip-book.d.ts",
9
- "homepage": "https://github.com/doradsoft/html-flip-book",
10
- "repository": {
11
- "type": "git",
12
- "url": "https://github.com/doradsoft/html-flip-book.git"
13
- },
14
- "bugs": {
15
- "url": "https://github.com/doradsoft/html-flip-book/issues"
16
- },
17
- "keywords": [
18
- "book",
19
- "flip-book",
20
- "react"
21
- ],
22
- "license": "MIT",
23
- "scripts": {
24
- "build": "vite build"
25
- },
26
- "dependencies": {
27
- "react": "^18.3.1",
28
- "react-dom": "^18.3.1"
29
- },
30
- "devDependencies": {
31
- "@types/react": "^18.3.3",
32
- "@types/react-dom": "^18.3.0",
33
- "@vitejs/plugin-react-refresh": "^1.3.6",
34
- "@vitejs/plugin-react-swc": "^3.7.0",
35
- "html-flip-book-base": "file:../base",
36
- "react-refresh": "^0.14.2",
37
- "typescript": "^5.5.3",
38
- "typescript-eslint": "^8.0.0-alpha.14",
39
- "vite": "^5.3.3",
40
- "vite-plugin-checker": "^0.7.1",
41
- "vite-plugin-dts": "^3.9.1",
42
- "vite-tsconfig-paths": "^4.3.2",
43
- "vitest": "^1.6.0"
44
- }
2
+ "name": "html-flip-book-react",
3
+ "description": "Flip Book React Component",
4
+ "version": "0.0.0-alpha.9",
5
+ "type": "module",
6
+ "author": "DoradSoft",
7
+ "main": "./dist/flip-book.js",
8
+ "types": "./dist/flip-book.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "import": "./dist/flip-book.js",
12
+ "types": "./dist/flip-book.d.ts"
13
+ },
14
+ "./toolbar": {
15
+ "import": "./dist/toolbar/index.js",
16
+ "types": "./dist/toolbar/index.d.ts"
17
+ }
18
+ },
19
+ "files": [
20
+ "dist"
21
+ ],
22
+ "homepage": "https://github.com/doradsoft/html-flip-book",
23
+ "repository": {
24
+ "type": "git",
25
+ "url": "git+https://github.com/doradsoft/html-flip-book.git"
26
+ },
27
+ "bugs": {
28
+ "url": "https://github.com/doradsoft/html-flip-book/issues"
29
+ },
30
+ "keywords": [
31
+ "book",
32
+ "flip-book",
33
+ "react"
34
+ ],
35
+ "license": "MIT",
36
+ "peerDependencies": {
37
+ "react": "^18.0.0",
38
+ "react-dom": "^18.0.0"
39
+ },
40
+ "dependencies": {
41
+ "html-flip-book-vanilla": "0.0.0-alpha.9"
42
+ },
43
+ "devDependencies": {
44
+ "@types/react": "^19.2.8",
45
+ "@types/react-dom": "^19.2.3"
46
+ }
45
47
  }
@@ -1,14 +0,0 @@
1
- import { default as React } from 'react';
2
- import { PageSemantics } from 'html-flip-book-base';
3
-
4
- interface FlipBookWrapperProps {
5
- pages: React.ReactNode[];
6
- className: string;
7
- pageSemantics?: PageSemantics;
8
- debug?: boolean;
9
- direction?: 'rtl' | 'ltr';
10
- }
11
- declare const FlipBookReact: React.FC<FlipBookWrapperProps>;
12
- export { FlipBookReact as FlipBook };
13
- export type { PageSemantics };
14
- //# sourceMappingURL=FlipBook.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"FlipBook.d.ts","sourceRoot":"","sources":["../src/FlipBook.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4B,MAAM,OAAO,CAAA;AAChD,OAAO,EAA4B,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAE7E,UAAU,oBAAoB;IAC5B,KAAK,EAAE,KAAK,CAAC,SAAS,EAAE,CAAA;IACxB,SAAS,EAAE,MAAM,CAAA;IACjB,aAAa,CAAC,EAAE,aAAa,CAAA;IAC7B,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,SAAS,CAAC,EAAE,KAAK,GAAG,KAAK,CAAA;CAE1B;AAED,QAAA,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CA6BjD,CAAA;AAED,OAAO,EAAE,aAAa,IAAI,QAAQ,EAAE,CAAA;AACpC,YAAY,EAAE,aAAa,EAAE,CAAA"}
@@ -1,3 +0,0 @@
1
- {
2
- "liveServer.settings.port": 5501
3
- }
package/example/README.md DELETED
@@ -1,47 +0,0 @@
1
- # scaffold-react-esm-vite
2
-
3
- Scaffold for React project implementing ESM by using Vite build tool.
4
-
5
- ## Description
6
-
7
- This is a base project for creating React applications with ECMAScript Modules (ESM). It's built using Vite and a variety of modern tools and packages.
8
-
9
- ## Installation
10
-
11
- First, clone the project. Then, use the package manager [npm](https://www.npmjs.com/) to install all dependencies for the project.
12
-
13
- ## Getting started
14
-
15
- To start the project, you will be using NPM scripts.
16
- Start the project in development mode:
17
-
18
- ```shell
19
- npm run dev
20
- ```
21
-
22
- ## Building the Project
23
-
24
- To create a build of the project, use the following NPM script:
25
-
26
- ```shell
27
- # Development mode
28
- npm run build
29
- # Production mode
30
- npm run build -- --mode production
31
- ```
32
-
33
- ## Running Tests
34
-
35
- The project uses vitest for testing. Run the following NPM script to execute the tests:
36
-
37
- ```shell
38
- npm run test
39
- ```
40
-
41
- ## Author
42
-
43
- Joan Lloret <juallom@gmail.com>
44
-
45
- ## License
46
-
47
- This project is licenced under the ISC License.
@@ -1,85 +0,0 @@
1
- # About the book
2
-
3
- * **This version was published on October 13 2021**
4
-
5
- This is an open-source introduction to SQL guide that will help you learn the basics of SQL and start using relational databases for your SysOps, DevOps, and Dev projects. No matter if you are a DevOps/SysOps engineer, developer, or just a Linux enthusiast, you will most likely have to use SQL at some point in your career.
6
-
7
- The guide is suitable for anyone working as a developer, system administrator, or a DevOps engineer and wants to learn the basics of SQL.
8
-
9
- ## About the author
10
-
11
- My name is Bobby Iliev, and I have been working as a Linux DevOps Engineer since 2014. I am an avid Linux lover and supporter of the open-source movement philosophy. I am always doing that which I cannot do in order that I may learn how to do it, and I believe in sharing knowledge.
12
-
13
- I think it's essential always to keep professional and surround yourself with good people, work hard, and be nice to everyone. You have to perform at a consistently higher level than others. That's the mark of a true professional.
14
-
15
- For more information, please visit my blog at [https://bobbyiliev.com](https://bobbyiliev.com), follow me on Twitter [@bobbyiliev_](https://twitter.com/bobbyiliev_) and [YouTube](https://www.youtube.com/channel/UCQWmdHTeAO0UvaNqve9udRw).
16
-
17
- ## Sponsors
18
-
19
- This book is made possible thanks to these fantastic companies!
20
-
21
- ### Materialize
22
-
23
- The Streaming Database for Real-time Analytics.
24
-
25
- [Materialize](https://materialize.com/) is a reactive database that delivers incremental view updates. Materialize helps developers easily build with streaming data using standard SQL.
26
-
27
- ### DigitalOcean
28
-
29
- DigitalOcean is a cloud services platform delivering the simplicity developers love and businesses trust to run production applications at scale.
30
-
31
- It provides highly available, secure, and scalable compute, storage, and networking solutions that help developers build great software faster.
32
-
33
- Founded in 2012 with offices in New York and Cambridge, MA, DigitalOcean offers transparent and affordable pricing, an elegant user interface, and one of the largest libraries of open source resources available.
34
-
35
- For more information, please visit [https://www.digitalocean.com](https://www.digitalocean.com) or follow [@digitalocean](https://twitter.com/digitalocean) on Twitter.
36
-
37
- If you are new to DigitalOcean, you can get a free $100 credit and spin up your own servers via this referral link here:
38
-
39
- [Free $100 Credit For DigitalOcean](https://m.do.co/c/2a9bba940f39)
40
-
41
- ### DevDojo
42
-
43
- The DevDojo is a resource to learn all things web development and web design. Learn on your lunch break or wake up and enjoy a cup of coffee with us to learn something new.
44
-
45
- Join this developer community, and we can all learn together, build together, and grow together.
46
-
47
- [Join DevDojo](https://devdojo.com?ref=bobbyiliev)
48
-
49
- For more information, please visit [https://www.devdojo.com](https://www.devdojo.com?ref=bobbyiliev) or follow [@thedevdojo](https://twitter.com/thedevdojo) on Twitter.
50
-
51
- ## Ebook PDF Generation Tool
52
-
53
- This ebook was generated by [Ibis](https://github.com/themsaid/ibis/) developed by [Mohamed Said](https://github.com/themsaid).
54
-
55
- Ibis is a PHP tool that helps you write eBooks in markdown.
56
-
57
- ## Book Cover
58
-
59
- The cover for this ebook was created with [Canva.com](https://www.canva.com/join/determined-cork-learn).
60
-
61
- If you ever need to create a graphic, poster, invitation, logo, presentation – or anything that looks good — give Canva a go.
62
-
63
- ## License
64
-
65
- MIT License
66
-
67
- Copyright (c) 2020 Bobby Iliev
68
-
69
- Permission is hereby granted, free of charge, to any person obtaining a copy
70
- of this software and associated documentation files (the "Software"), to deal
71
- in the Software without restriction, including without limitation the rights
72
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
73
- copies of the Software, and to permit persons to whom the Software is
74
- furnished to do so, subject to the following conditions:
75
-
76
- The above copyright notice and this permission notice shall be included in all
77
- copies or substantial portions of the Software.
78
-
79
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
80
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
81
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
82
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
83
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
84
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
85
- SOFTWARE.
@@ -1,39 +0,0 @@
1
- # Databases
2
-
3
- Before we dive deep into SQL, let's quickly define what a database is.
4
-
5
- The definition of databases from Wikipedia is:
6
-
7
- > A database is an organized collection of data, generally stored and accessed electronically from a computer system.
8
-
9
- In other words, a database is a collection of data stored and structured in different database tables.
10
-
11
- ## Tables and columns
12
-
13
- You've most likely worked with spreadsheet systems like Excel or Google Sheets. At the very basic, database tables are quite similar to spreadsheets.
14
-
15
- Each table has different **columns** which could contain different types of data.
16
-
17
- For example, if you have a todo list app, you would have a database, and in your database, you would have different tables storing different information like:
18
-
19
- * Users - In the users table, you would have some data for your users like: `username`, `name`, and `active`, for example.
20
- * Tasks - The tasks table would store all of the tasks that you are planning to do. The columns of the tasks table would be for example, `task_name`, `status`, `due_date` and `priority`.
21
-
22
- The Users table will look like this:
23
-
24
- ```
25
- +----+----------+---------------+--------+
26
- | id | username | name | active |
27
- +----+----------+---------------+--------+
28
- | 1 | bobby | Bobby Iliev | true |
29
- | 2 | grisi | Greisi I. | true |
30
- | 3 | devdojo | Dev Dojo | false |
31
- +----+----------+---------------+--------+
32
- ```
33
-
34
- Rundown of the table structure:
35
- * We have 4 columns: `id`, `username`, `name` and `active`.
36
- * We also have 3 entries/users.
37
- * The `id` column is a unique identifier of each user and is auto-incremented.
38
-
39
- In the next chapter, we will learn how to install MySQL and create our first database.
@@ -1,162 +0,0 @@
1
- # MySQL
2
-
3
- Now that you know what a database, table, and column are, the next thing that you would need to do is install a database service where you would be running your SQL queries on.
4
-
5
- We will be using MySQL as it is free, open-source, and very widely used.
6
-
7
- ## Installing MySQL
8
-
9
- Depending on your operating system, to install MySQL run the following commands.
10
-
11
- ### Install MySQL on Ubuntu
12
-
13
- To install MySQL on a Linux or Ubuntu machine, run the following commands:
14
-
15
- * First update your `apt` repository:
16
-
17
- ```
18
- sudo apt update -y
19
- ```
20
-
21
- * Then install MySQL:
22
-
23
- ```
24
- sudo apt install mysql-server mysql-client
25
- ```
26
-
27
- We are installing two packages, one is the actual MySQL server, and the other is the MySQL client, which would allow us to connect to the MySQL server and run our queries.
28
-
29
- To check if MySQL is running, run the following command:
30
-
31
- ```
32
- sudo systemctl status mysql.service
33
- ```
34
- To secure your MySQL server, you could run the following command:
35
-
36
- ```
37
- sudo mysql_secure_installation
38
- ```
39
-
40
- Then follow the prompt and choose a secure password and save it in a secure place like a password manager.
41
-
42
- With that, you would have MySQL installed on your Ubuntu server. The above should also work just fine on Debian.
43
-
44
- ### Install MySQL on Mac
45
-
46
- I would recommend installing MySQL using [Homebrew]():
47
-
48
- ```
49
- brew install mysql
50
- ```
51
-
52
- After that, start MySQL:
53
-
54
- ```
55
- brew services start mysql
56
- ```
57
-
58
- And finally, secure it:
59
-
60
- ```
61
- mysql_secure_installation
62
- ```
63
-
64
- In case that you ever need to stop the MySQL service, you could do so with the following command:
65
-
66
- ```
67
- brew services stop mysql
68
- ```
69
-
70
- ### Install MySQL on Windows
71
-
72
- To install MySQL on Windows, I would recommend following the steps from the official documentation here:
73
-
74
- [https://dev.mysql.com/doc/refman/8.0/en/windows-installation.html](https://dev.mysql.com/doc/refman/8.0/en/windows-installation.html)
75
-
76
- ## Accessing MySQL via CLI
77
-
78
- To access MySQL run the `mysql` command followed by your user:
79
-
80
- ```
81
- mysql -u root -p
82
- ```
83
-
84
- ## Creating a database
85
-
86
- After that, switch to the `demo` database that we created in the previous chapter:
87
-
88
- ```sql
89
- USE demo;
90
- ```
91
-
92
- To exit the just type the following:
93
-
94
- ```
95
- exit;
96
- ```
97
-
98
- ## Configuring `.my.cnf`
99
-
100
- By configuring the `~/.my.cnf` file in your user's home directory, MySQL would allow you to log in without prompting you for a password.
101
-
102
- To make that change, what you need to do is first create a `.my.cnf` file in your user's home directory:
103
-
104
- ```
105
- touch ~/.my.cnf
106
- ```
107
-
108
- After that, set secure permissions so that other regular users could not read the file:
109
-
110
- ```
111
- chmod 600 ~/.my.cnf
112
- ```
113
-
114
- Then using your favourite text editor, open the file:
115
-
116
- ```
117
- nano ~/.my.cnf
118
- ```
119
-
120
- And add the following configuration:
121
-
122
- ```
123
- [client]
124
- user=YOUR_MYSQL_USERNAME
125
- password=YOUR_MYSQL_PASSWORD
126
- ```
127
-
128
- Make sure to update your MySQL credentials accordingly, then save the file and exit.
129
-
130
- After that, if you run just `mysql`, you will be authenticated directly with the credentials that you've specified in the `~/.my.cnf` file without being prompted for a password.
131
-
132
- ## The mysqladmin command
133
-
134
- As a quick test, you could check all of your open SQL connections by running the following command:
135
-
136
- ```
137
- mysqladmin proc
138
- ```
139
-
140
- The `mysqladmin` tool would also use the client details from the `~/.my.cnf` file, and it would list your current MySQL process list.
141
-
142
- Another cool thing that you could try doing is combining this with the `watch` command and kind of monitor your MySQL connections in almost real-time:
143
-
144
- ```
145
- watch -n1 mysqladmin proc
146
- ```
147
-
148
- To stop the `watch` command, just hit `CTRL+C`
149
-
150
- ## GUI clients
151
-
152
- If you prefer using GUI clients, you could take a look a the following ones and install them locally on your laptop:
153
-
154
- * [MySQL Workbench](https://www.mysql.com/products/workbench/)
155
- * [Sequel Pro](https://www.sequelpro.com/)
156
- * [TablePlus](https://tableplus.com/)
157
-
158
- This will allow you to connect to your database via a graphical interface rather than the `mysql` command-line tool.
159
-
160
- If you want to have a production-ready MySQL database, I would recommend giving DigitalOcean a try:
161
-
162
- [Worry-free managed database hosting](https://www.digitalocean.com/products/managed-databases/)