From b0cb5f382565832b6a5a39d5663dc5384e2bcaf3 Mon Sep 17 00:00:00 2001
From: Alex Styl <1665273+alexstyl@users.noreply.github.com>
Date: Sat, 27 Apr 2024 19:48:28 +0300
Subject: [PATCH] Initial Commit
---
.github/workflows/docs.yml | 30 +
.gitignore | 20 +
LICENSE | 21 +
README.md | 19 +
build.gradle.kts | 24 +
demo/build.gradle.kts | 83 ++
demo/src/androidMain/AndroidManifest.xml | 15 +
demo/src/androidMain/kotlin/MainActivity.kt | 25 +
demo/src/commonMain/kotlin/App.kt | 447 ++++++++
demo/src/desktopMain/kotlin/Main.kt | 5 +
demo/src/iosMain/kotlin/iOSMain.kt | 5 +
demo/src/wasmJsMain/kotlin/main.kt | 7 +
demo/src/wasmJsMain/resources/index.html | 12 +
docs/composables.svg | 16 +
docs/index.md | 243 ++++
docs/preview/273.js | 2 +
docs/preview/273.js.map | 1 +
docs/preview/META-INF/MANIFEST.MF | 2 +
docs/preview/composeApp.js | 2 +
docs/preview/composeApp.js.map | 1 +
docs/preview/demo.wasm | Bin 0 -> 5425850 bytes
docs/preview/e8a42516ed7440038c2b.wasm | Bin 0 -> 8027441 bytes
docs/preview/index.html | 12 +
docs/preview/skiko.js | 87 ++
docs/preview/skiko.mjs | 1015 +++++++++++++++++
docs/preview/skiko.wasm | Bin 0 -> 8027441 bytes
gradle.properties | 13 +
gradle/libs.versions.toml | 16 +
gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 63721 bytes
gradle/wrapper/gradle-wrapper.properties | 7 +
gradlew | 249 ++++
gradlew.bat | 92 ++
iosApp/Configuration/Config.xcconfig | 3 +
iosApp/iosApp.xcodeproj/project.pbxproj | 398 +++++++
.../AccentColor.colorset/Contents.json | 11 +
.../AppIcon.appiconset/Contents.json | 14 +
.../AppIcon.appiconset/app-icon-1024.png | Bin 0 -> 67285 bytes
iosApp/iosApp/Assets.xcassets/Contents.json | 6 +
iosApp/iosApp/ContentView.swift | 21 +
iosApp/iosApp/Info.plist | 50 +
.../Preview Assets.xcassets/Contents.json | 6 +
iosApp/iosApp/iOSApp.swift | 10 +
menu/build.gradle.kts | 125 ++
menu/src/commonMain/kotlin/Menu.kt | 238 ++++
mkdocs.yml | 43 +
scripts/update_demo.sh | 14 +
settings.gradle.kts | 38 +
47 files changed, 3448 insertions(+)
create mode 100644 .github/workflows/docs.yml
create mode 100644 .gitignore
create mode 100644 LICENSE
create mode 100644 README.md
create mode 100644 build.gradle.kts
create mode 100644 demo/build.gradle.kts
create mode 100644 demo/src/androidMain/AndroidManifest.xml
create mode 100644 demo/src/androidMain/kotlin/MainActivity.kt
create mode 100644 demo/src/commonMain/kotlin/App.kt
create mode 100644 demo/src/desktopMain/kotlin/Main.kt
create mode 100644 demo/src/iosMain/kotlin/iOSMain.kt
create mode 100644 demo/src/wasmJsMain/kotlin/main.kt
create mode 100644 demo/src/wasmJsMain/resources/index.html
create mode 100644 docs/composables.svg
create mode 100644 docs/index.md
create mode 100644 docs/preview/273.js
create mode 100644 docs/preview/273.js.map
create mode 100644 docs/preview/META-INF/MANIFEST.MF
create mode 100644 docs/preview/composeApp.js
create mode 100644 docs/preview/composeApp.js.map
create mode 100644 docs/preview/demo.wasm
create mode 100644 docs/preview/e8a42516ed7440038c2b.wasm
create mode 100644 docs/preview/index.html
create mode 100644 docs/preview/skiko.js
create mode 100644 docs/preview/skiko.mjs
create mode 100755 docs/preview/skiko.wasm
create mode 100644 gradle.properties
create mode 100644 gradle/libs.versions.toml
create mode 100644 gradle/wrapper/gradle-wrapper.jar
create mode 100644 gradle/wrapper/gradle-wrapper.properties
create mode 100755 gradlew
create mode 100644 gradlew.bat
create mode 100644 iosApp/Configuration/Config.xcconfig
create mode 100644 iosApp/iosApp.xcodeproj/project.pbxproj
create mode 100644 iosApp/iosApp/Assets.xcassets/AccentColor.colorset/Contents.json
create mode 100644 iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/Contents.json
create mode 100644 iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/app-icon-1024.png
create mode 100644 iosApp/iosApp/Assets.xcassets/Contents.json
create mode 100644 iosApp/iosApp/ContentView.swift
create mode 100644 iosApp/iosApp/Info.plist
create mode 100644 iosApp/iosApp/Preview Content/Preview Assets.xcassets/Contents.json
create mode 100644 iosApp/iosApp/iOSApp.swift
create mode 100644 menu/build.gradle.kts
create mode 100644 menu/src/commonMain/kotlin/Menu.kt
create mode 100644 mkdocs.yml
create mode 100755 scripts/update_demo.sh
create mode 100644 settings.gradle.kts
diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml
new file mode 100644
index 0000000..2ceaf10
--- /dev/null
+++ b/.github/workflows/docs.yml
@@ -0,0 +1,30 @@
+name: ci
+on:
+ push:
+ branches:
+ - main
+permissions:
+ contents: write
+jobs:
+ deploy:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - name: Configure Git Credentials
+ run: |
+ git config user.name github-actions[bot]
+ git config user.email 41898282+github-actions[bot]@users.noreply.github.com
+ - uses: actions/setup-python@v5
+ with:
+ python-version: 3.x
+ - name: Prepare demo app
+ run: bash /scripts/update_demo.sh
+ - run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV
+ - uses: actions/cache@v4
+ with:
+ key: mkdocs-material-${{ env.cache_id }}
+ path: .cache
+ restore-keys: |
+ mkdocs-material-
+ - run: pip install mkdocs-material
+ - run: mkdocs gh-deploy --force
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..f4e47d3
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,20 @@
+*.iml
+.gradle
+**/build/
+xcuserdata
+!src/**/build/
+local.properties
+.idea
+kotlin-js-store/
+.DS_Store
+captures
+.externalNativeBuild
+.cxx
+*.xcodeproj/*
+!*.xcodeproj/project.pbxproj
+!*.xcodeproj/xcshareddata/
+!*.xcodeproj/project.xcworkspace/
+!*.xcworkspace/contents.xcworkspacedata
+**/xcshareddata/WorkspaceSettings.xcsettings
+venv/
+.cache/
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..181bc8f
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2024 Composable Horizons
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..863e6b5
--- /dev/null
+++ b/README.md
@@ -0,0 +1,19 @@
+# Compose Menu (Dropdown)
+
+An unstyled Composable component for Compose Multiplatform that can be used to implement Dropdown Menus with the styling of your choice.
+
+Comes with built-in Keyboard management and animation support. Supports Compose Desktop, Web (WASM), Android and iOS.
+
+## Installation
+
+Ensure you have `mavenCentral()` to your `dependencyResolutionManagement{}` block, then add the dependency:
+
+```kotlin
+dependencies {
+ implementation("com.composables.ui:menu:0.0.2")
+}
+```
+
+## Contributing
+
+We are currently accepting contributions in the form of bug reports and feature requests, in the form of Github issues.
\ No newline at end of file
diff --git a/build.gradle.kts b/build.gradle.kts
new file mode 100644
index 0000000..eac890b
--- /dev/null
+++ b/build.gradle.kts
@@ -0,0 +1,24 @@
+import com.android.build.gradle.internal.cxx.configure.gradleLocalProperties
+
+plugins {
+ alias(libs.plugins.jetbrainsCompose) apply false
+ alias(libs.plugins.kotlinMultiplatform) apply false
+ id("com.android.application") version "8.2.0" apply false
+ id("com.android.library") version "8.2.0" apply false
+ id("org.jetbrains.dokka").version("1.9.10").apply(false)
+ id("io.github.gradle-nexus.publish-plugin").version("2.0.0-rc-1")
+}
+
+nexusPublishing {
+ repositories {
+ sonatype {
+ with(gradleLocalProperties(rootDir)) {
+ stagingProfileId.set(getProperty("sonatype.stagingProfileId") ?: System.getenv("SONATYPE_STAGING_PROFILE_ID"))
+ username.set(getProperty("sonatype.username") ?: System.getenv("OSSRH_USERNAME"))
+ password.set(getProperty("sonatype.password") ?: System.getenv("OSSRH_PASSWORD"))
+ nexusUrl.set(uri("https://s01.oss.sonatype.org/service/local/"))
+ snapshotRepositoryUrl.set(uri("https://s01.oss.sonatype.org/content/repositories/snapshots/"))
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/demo/build.gradle.kts b/demo/build.gradle.kts
new file mode 100644
index 0000000..a02372c
--- /dev/null
+++ b/demo/build.gradle.kts
@@ -0,0 +1,83 @@
+import org.jetbrains.kotlin.gradle.targets.js.dsl.ExperimentalWasmDsl
+
+plugins {
+ alias(libs.plugins.kotlinMultiplatform)
+ alias(libs.plugins.jetbrainsCompose)
+ id("com.android.application")
+}
+
+kotlin {
+ @OptIn(ExperimentalWasmDsl::class) wasmJs {
+ moduleName = "demo"
+ browser {
+ commonWebpackConfig {
+ outputFileName = "composeApp.js"
+ }
+ }
+ binaries.executable()
+ }
+
+ jvm("desktop")
+
+ androidTarget {
+ compilations.all {
+ kotlinOptions {
+ jvmTarget = "1.8"
+ }
+ }
+ }
+
+ listOf(iosX64(), iosArm64(), iosSimulatorArm64()).forEach { iosTarget ->
+ iosTarget.binaries.framework {
+ baseName = "ComposeApp"
+ isStatic = true
+ }
+ }
+
+ sourceSets {
+ commonMain.dependencies {
+ implementation(compose.runtime)
+ implementation(compose.foundation)
+ implementation(compose.ui)
+ implementation(compose.components.resources)
+ implementation(project(":menu"))
+ }
+
+ val desktopMain by getting {
+ dependencies {
+ implementation(compose.desktop.common)
+ implementation(compose.desktop.currentOs)
+ }
+ }
+
+ val androidMain by getting {
+ dependencies {
+ implementation ("androidx.compose.ui:ui:1.6.6")
+ implementation ("androidx.activity:activity-compose:1.9.0")
+ }
+ }
+ }
+}
+
+compose.experimental {
+ web.application {}
+}
+
+compose.desktop {
+ application {
+ mainClass = "MainKt"
+ }
+}
+
+android {
+ namespace = "com.composables.ui.demo"
+ compileSdk = 34
+ defaultConfig {
+ minSdk = 21
+ targetSdk = 34
+
+ applicationId = "com.composables.ui.demo"
+ versionCode = 1
+ versionName = "1.0.0"
+ }
+}
\ No newline at end of file
diff --git a/demo/src/androidMain/AndroidManifest.xml b/demo/src/androidMain/AndroidManifest.xml
new file mode 100644
index 0000000..3be16f2
--- /dev/null
+++ b/demo/src/androidMain/AndroidManifest.xml
@@ -0,0 +1,15 @@
+
+
{var e=H_.getNewId(H_.contexts),r={handle:e,attributes:a,version:a.majorVersion,GLctx:_};return _.canvas&&(_.canvas.GLctxObject=r),H_.contexts[e]=r,(void 0===a.enableExtensionsByDefault||a.enableExtensionsByDefault)&&H_.initExtensions(r),a.renderViaOffscreenBackBuffer&&H_.createOffscreenFramebuffer(r),e},makeContextCurrent:_=>(H_.currentContext=H_.contexts[_],t.ctx=aa=H_.currentContext&&H_.currentContext.GLctx,!(_&&!aa)),getContext:_=>H_.contexts[_],deleteContext:_=>{H_.currentContext===H_.contexts[_]&&(H_.currentContext=null),"object"==typeof JSEvents&&JSEvents.removeAllHandlersOnTarget(H_.contexts[_].GLctx.canvas),H_.contexts[_]&&H_.contexts[_].GLctx.canvas&&(H_.contexts[_].GLctx.canvas.GLctxObject=void 0),H_.contexts[_]=null},initExtensions:_=>{if(_||(_=H_.currentContext),!_.initExtensionsDone){_.initExtensionsDone=!0;var a,e=_.GLctx;(a=e).dibvbi=a.getExtension("WEBGL_draw_instanced_base_vertex_base_instance"),(_=>{_.mdibvbi=_.getExtension("WEBGL_multi_draw_instanced_base_vertex_base_instance")})(e),_.version>=2&&(e.disjointTimerQueryExt=e.getExtension("EXT_disjoint_timer_query_webgl2")),(_.version<2||!e.disjointTimerQueryExt)&&(e.disjointTimerQueryExt=e.getExtension("EXT_disjoint_timer_query")),(_=>{_.multiDrawWebgl=_.getExtension("WEBGL_multi_draw")})(e),(e.getSupportedExtensions()||[]).forEach((_=>{_.includes("lose_context")||_.includes("debug")||e.getExtension(_)}))}},getExtensions(){var _=aa.getSupportedExtensions()||[];return _.concat(_.map((_=>"GL_"+_)))}},U_=_=>{aa.bindVertexArray(H_.vaos[_])},O_=U_,W_=U_,N_=(_,a)=>(_>>>0)+4294967296*a,q_=(_,a)=>{for(var e=0;e<_;e++){var r=C[a+4*e>>2];aa.deleteVertexArray(H_.vaos[r]),H_.vaos[r]=null}},K_=q_,X_=q_,Q_=[],$_=(_,a,e,r)=>{aa.drawElements(_,a,e,r)},Y_=$_,J_=(_,a,e,r)=>{for(var t=0;t<_;t++){var i=aa[e](),n=i&&H_.getNewId(r);i?(i.name=n,r[n]=i):H_.recordError(1282),C[a+4*t>>2]=n}};function Z_(_,a){J_(_,a,"createVertexArray",H_.vaos)}var _a,aa,ea=Z_,ra=Z_,ta=(_,a,e)=>{if(a){var r=void 0;switch(_){case 36346:r=1;break;case 36344:return void(0!=e&&1!=e&&H_.recordError(1280));case 34814:case 36345:r=0;break;case 34466:var t=aa.getParameter(34467);r=t?t.length:0;break;case 33309:if(H_.currentContext.version<2)return void H_.recordError(1282);r=2*(aa.getSupportedExtensions()||[]).length;break;case 33307:case 33308:if(H_.currentContext.version<2)return void H_.recordError(1280);r=33307==_?3:0}if(void 0===r){var i=aa.getParameter(_);switch(typeof i){case"number":r=i;break;case"boolean":r=i?1:0;break;case"string":return void H_.recordError(1280);case"object":if(null===i)switch(_){case 34964:case 35725:case 34965:case 36006:case 36007:case 32873:case 34229:case 36662:case 36663:case 35053:case 35055:case 36010:case 35097:case 35869:case 32874:case 36389:case 35983:case 35368:case 34068:r=0;break;default:return void H_.recordError(1280)}else{if(i instanceof Float32Array||i instanceof Uint32Array||i instanceof Int32Array||i instanceof Array){for(var n=0;n DG
zjlsDXoR7hU7+j3Or5Id}!Phak5`%AI@NEpP#^72EuE*d;3~t8YRt#>(;7$zg#^7EI
z?#JLk48DuO!x%h@!Q&WwAA=_`=u(N!K_AATYYaY$!N)Q9BnI7L&^-n{V$d@Ny<*Ti
z27O}CHwOJ;&_4zPVlXfUgJLi^218;nGzPDGjlsDXoR7hU7+j3Or5Id}!Phak5`%AI@NEpP#^72Eu7{v%ZYW45
z|9OcDUmY}_%4==0&&(_%100!=0||_%400==0),ha=[31,29,31,30,31,30,31,31,30,31,30,31],ca=[31,28,31,30,31,30,31,31,30,31,30,31],da=[],ua=_=>{var a=da[_];return a||(_>=da.length&&(da.length=_+1),da[_]=a=_a.get(_)),a},ma=function(_,a,e,r){_||(_=this),this.parent=_,this.mount=_.mount,this.mounted=null,this.id=h_.nextInode++,this.name=a,this.mode=e,this.node_ops={},this.stream_ops={},this.rdev=r};Object.defineProperties(ma.prototype,{read:{get:function(){return!(365&~this.mode)},set:function(_){_?this.mode|=365:this.mode&=-366}},write:{get:function(){return!(146&~this.mode)},set:function(_){_?this.mode|=146:this.mode&=-147}},isFolder:{get:function(){return h_.isDir(this.mode)}},isDevice:{get:function(){return h_.isChrdev(this.mode)}}}),h_.FSNode=ma,h_.createPreloadedFile=(_,a,e,r,t,i,n,s,g,k)=>{var b=a?a_.resolve(Z.join2(_,a)):_;function l(e){function o(e){k&&k(),s||((_,a,e,r,t,i)=>{h_.createDataFile(_,a,e,r,t,i)})(_,a,e,r,t,g),i&&i(),z()}((_,a,e,r)=>{"undefined"!=typeof Browser&&Browser.init();var t=!1;return j_.forEach((i=>{t||i.canHandle(a)&&(i.handle(_,a,e,r),t=!0)})),t})(e,b,o,(()=>{n&&n(),z()}))||o(e)}L(),"string"==typeof e?((_,a,e,r)=>{var t=r?"":`al ${_}`;o(_,(e=>{e||V(`Loading data file "${_}" failed (no arrayBuffer).`),a(new Uint8Array(e)),t&&z()}),(a=>{if(!e)throw`Loading data file "${_}" failed.`;e()})),t&&L()})(e,(_=>l(_)),n):l(e)},h_.staticInit(),(()=>{for(var _=new Array(256),a=0;a<256;++a)_[a]=String.fromCharCode(a);o_=_})(),g_=t.BindingError=class extends Error{constructor(_){super(_),this.name="BindingError"}},t.InternalError=class extends Error{constructor(_){super(_),this.name="InternalError"}},Object.assign(y_.prototype,{get(_){return this.allocated[_]},has(_){return void 0!==this.allocated[_]},allocate(_){var a=this.freelist.pop()||this.allocated.length;return this.allocated[a]=_,a},free(_){this.allocated[_]=void 0,this.freelist.push(_)}}),F_.allocated.push({value:void 0},{value:null},{value:!0},{value:!1}),F_.reserved=F_.allocated.length,t.count_emval_handles=()=>{for(var _=0,a=F_.reserved;a0&&(s=a.slice(i+1),r=parseInt(s)>>>0,t=a.slice(0,i));var n=_.uniformSizeAndIdsByName[t];if(n&&rS0j=*s)N;f?J1Z5b?VwBY=dr|hG970)uvIk`m$}yCkD7#RWp`1rKgYqTHDwItq
z>rl3#Y(&|Qat`G*%0ZObDDzQHq0B^Ci?SJIJIY~{^(cGb(+(UrpzKCDfN}z52+CI|
z*HC7l3~fhA(>Cb>{jQuq<>VH|t~>s|jpM?$X|DHSS=(eV_~-n*lnj&O3^~r{W4mM(
zbiPDc!GAX+veQr4#>RW8G%zY3hg63A6KCib{S?*AQJV
zt`&%$SHIo}mSVe1(lr~uAC#}=+(tkEn9ecJ2$^zTjNPnniFN(%@|PE3m>+bK9t
zTdCOG?_R)T$v`QEae=hkm!RA^3eGVc<6w_xPoVmT}sx(96az
zqw&K
G)sdJCZLPozscDP^I|
zY25F4m?Zup9!hGww83vg$RC(udz>IP&S6vaC0$s@UzfvllrVT7$KWJ8Oas8FdW4=G
zr3W%X*+|#ORE1eqKwa|_FBIJ%
z(Y4%ky;WT6PI0Y!#kC$3*Lql7>v3_d*7eI@6vI;+Nu=-$%FfYnn(Nzt!k8AX{B|YG
znV*!0PdlHA8{%}&H&mHv!aKvmtcg!$d&qWF8pJ2ERhTxY
zP0m&UE%(y5ISO^`=PHt_RWr{+qSwL9SLl48XJUDQCzc*ARKyEBE%GR$zet5*qP
aX(E5a3s)OhWSI3V4I4I$Zo9FJM
zJ+I44y-FIzWeV9eey~dc_XNFRLD{TO0Rw#Lr-EcX`n&;UBg&>f_AgzlW|gXWmvs18
ztYUWEh6Z2hnGukJtcDF{jf&}(H;LGtidn0IWUIabe4T?fr1+?;gV2=ej<4KNETPz_
zfGmn$)ojYcjb^jMXo~OOJLk4Ip>uAlgI2R_wkedjZ;!!_80-u|)$CG`tj37gF|3;1
zMS?v=g1z~Ive~Bs_Orq4SCCA{xzKO8!5nZxbTt_9_U51y;(C$xsywO0g6>`Ma{#J{
zR2u1hS_VJ-r6MmW8q8tE+-BcDvBQWv+DlE7^@nL=arer?L-SZ7WMG3>k02W44
z!@#HBO|Ft`1rXBL&1Q#djS8yJhV}nr?>(FBIFdC@hyp;-Yy|?SD)trAoJN5t&}??c
zc6V&ec7Fr@0cn=!+nR0Le%k#<jx-Xe~%+K`0VhYe{IWwbp{%=Y1nG^PECep#b*n
z={t5wRGv3H+&w%zJVZvu$rCE3K^x)U7q-8pumo+)j$AMrv!{|J#m*A4eK;%qB|;dQ
z6?T;{@OY+@foXR}#JnpC7Rc`v_GIK_M!PU}Iv6dpH_x2OZ=yTnhLr8gGEmk<%1qv0
zJNZB{`IRP1xSJIY7LhwP?)guQR);c@tJO9A{o^fvqR^l6%q*kZC+xQ$&NI64dsk@-
z3G46dpBg9IG*PGjhl-%{!@`kVR66;A;n